Wrong execution path picked by C# compiler when mixing generic and non-generic method signatures.
Note: this entry has moved.
I've found what seems like a bug in the C# compiler which makes the execution path of your code unpredictable. The scenario is laid out in the product feedback bug but a brief repro will hopefully suffice to convince you of its severity.
Basically, if you have the following class definition:
public class MyClass
{
public void Add(object value) { ... }
public void Add(BaseType value) { ... }
public T Add<T>(T value) { ... }
}
Assuming DerivedType is a class inheriting from BaseType, the following very strange and highly unexpected behavior will happen:
// The method with the non-generic signature is called as expected.
new MyClass().Add(new object());
// The method call below should never compile as the method receiving an object returns **void**
// The method with the generic signature is called ?!?!
object o = new MyClass().Add("hola");
// Anything that is not exactly of type object will go the generic method :S:S
// The match for the type is *exact* meaning that even
// if I have a method of a matching signature according to
// common polymorphic behavior (passing a derived type),
// the generic version is called instead of the expected one.
// the method below should never compile as the method returns **void**
object o2 = new MyClass().Add(new DerivedType());
The worst case scenario is if the method receiving a BaseType returned a BaseType instead of void, you would never know that what's actually being executed is the generic method instead of the expected method (for the second example, passing a new DerivedType), as the returned type would match, but the execution path will never be what you expected.
I believe this is pretty serious, and should get inmediate attention before it's too late. Please vote for the bug if you agree.