我遇到了一个我没想到的超载解决问题。显然,编译器解析了对MyPrint
方法的调用,该方法将"Hello world"
传递给派生类中的MyPrint<T>(T : struct)
而不是基类中定义的MyPrint(string)
。由于解析器选择的方法不接受字符串,因此出现编译错误。
我认为它与Jon Skeet wrote in his book和Eric Lippert on his blog这个脆弱的基类问题有关。 Lippert引用标准说:
如果派生中的任何方法,基类中的方法不是候选者 课程适用。
但是我没有看到派生类中的任何方法适用,编译器也没有从错误中判断出来。我想知道两件事:为什么它以这种方式工作,我怎样才能让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());
}
}
答案 0 :(得分:2)
你已经找到了一半的原因,但是你还需要Constraints are not part of the signature.结合“如果派生类中的任何方法适用,基类中的方法不是候选者”,你可以在重载解析过程中得到它两个看起来像MyPrint(string)
的方法因此适用,因此选择了派生程度最高的类中的方法。只有在那之后才检查约束,然后失败。
答案 1 :(得分:0)
如果你在派生类中定义它,你可以使它工作:
public new void MyPrint(string value)
{
base.MyPrint(value);
}
至于“为什么”,抱歉我不知道。可能C# Language Specification可以帮助回答这个问题。