Я столкнулся с проблемой разрешения перегрузки, которую я не ожидал. По-видимому, компилятор скорее разрешает вызов метода MyPrint
, передавая "Hello world"
MyPrint<T>(T : struct)
в производном классе, чем MyPrint(string)
, определенному в базовом классе. И поскольку метод, выбранный преобразователем, не будет принимать строку, я получаю ошибку компилятора.
Полагаю, это связано с проблемой хрупкого базового класса, как Джон Скит написал в своей книге и Эрик Липперт в своем блоге . Липперт цитирует стандарт так:
Методы в базовом классе не являются кандидатами, если какой-либо метод в производном
класс применим.
Но я не вижу применимости какого-либо метода в производном классе, равно как и компилятор, судя по ошибке. Я хотел бы знать две вещи: почему это работает таким образом, и как я могу позволить C # делать то, что я хочу, чтобы он делал снова?
Придуманный пример, демонстрирующий проблему:
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());
}
}