I ran in an overloading resolution problem which I did not expect. Apparently the compiler rather resolves a call to the MyPrint
method passing "Hello world"
to the MyPrint<T>(T : struct)
in the derived class than to the MyPrint(string)
defined in the base class. And since the method that the resolver chose will not accept the string, I get a compiler error.
I suppose it has to do with the Brittle Base Class problem as Jon Skeet wrote in his book, and Eric Lippert on his blog. Lippert quotes the standard as saying:
Methods in a base class are not candidates if any method in a derived class is applicable.
But I don't see any method in the derived class being applicable, and neither does the compiler judging from the error. I would like to know two things: why does it work this way, and how can I let C# do what I want it to do again?
Contrived example demonstrating the problem:
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
d.MyPrint(10);
// ERROR: The type 'string' must be a non-nullable value type
// in order to use it as parameter 'T'
// in the generic type or method 'Derived.MyPrint<T>(T)'.
d.MyPrint("Hello world!");
}
}
class Base
{
// I print only strings.
public void MyPrint(string value)
{
Console.WriteLine("String: " + value);
}
}
class Derived : Base
{
// I print any primitive type, enums and DateTime,
// but NOT string (since that is not a value type).
public void MyPrint<T>(T value)
where T : struct, IConvertible
{
Console.WriteLine("IConvertible: " + value.ToString());
}
}