Lets say you have this code:
So far so good. Now someone comes along and adds an overload to Foo specifically for Reptiles.
What should happen? Well since Foo<T>(T) isn’t a viable candidate, it should continue to use Foo(Animal).
What actually happens is you get this error message.
The type ‘ConsoleApplication2.Giraffe’ cannot be used as type parameter ‘T’ in the generic type or method ‘ConsoleApplication2.Program.Foo<T>(T)’. There is no implicit reference conversion from ‘ConsoleApplication2.Giraffe’ to ‘ConsoleApplication2.Reptile’.
Eric Lippert tells us that the “constraints are not part of the signature”, which is of course easily verifiable. But then he goes on to say C# is correct in throwing a compiler error in this scenario because that’s what the C# specification says that it should do.
Lets see the same code in Visual Basic:
No errors here.
So yea, the C# compiler’s overload resolution code is broken. It may match the specification, but unless someone can come up with a really good reason for that behavior it just means the specification is also broken.
By the way, you can fix the C# code by explicit casting.
Three sets of parens to VB’s one, that sounds about right.