If I have a base class
class Foo : IClonable {
public object virtual Clone(){ return new Foo(); }
}
and a child class incorrectly overriding clone with new
instead of override
. It's a simplification of a bug in a third party library I'm trying to work around.
class Bar : Foo {
public new Clone() { return new Bar(); }
}
and then I have two methods
public static T Bang(T source)
where T : Foo
{
return (T) source.Clone();
}
and
public static Bar Bang(Bar source)
{
return (Bar) source.Clone();
}
now if I invoke the first one with an instance of Bar
I get a Foo
back. If I invoke the second I get Bar
back.
I'm curious as to why the generic version doesn't get the new
version of Clone()
but rather the inherited version.
Is it that the type T
is erased after the constraints are met and then it just behaves using the base class?
Is it that the type T is erased after the constraints are met and then it just behaves using the base class?
It depends on what you mean by "the type T
is erased". It's not erased in the same way that it is in Java - the type argument is available at execution time, so if you write:
Console.WriteLine(typeof(T));
that will print Bar
.
However, the compiler needs to determine which method to call when it compiles your first Bang
method is that the value is of type Foo
or some subtype. It has to generate IL calling one method based on that. It's not like the compiler generates a new Bang
method for every different T
, using the actual type T
to perform method resolution etc.
In other words, as far as the compiler is concerned your method is equivalent to:
public static T Bang<T>(Foo source)
where T : Foo
{
return (T) source.Clone();
}
Note the change of the parameter type from T
to Foo
, because that's all the information the compiler has to go on.
(I'm assuming that you understand that your two Clone
methods are mostly unrelated as far as the compiler and CLR are concerned; they happen to have the same name, but one doesn't override the other polymorphically.)
See more on this question at Stackoverflow