我有一个继承自另一个类的类,允许使用可空值。但是当我使用非可空值时,它无论如何都会使用重载为空。
我不明白为什么类c2的功能在这段代码中掩盖了类c1的功能:
class c1
{
public void fn1(int value)
{
Console.WriteLine("value {0} is normal", value);
}
public void fn1(int? value)
{
Console.WriteLine("value {0} is nullable", value);
}
public void fn2(int value)
{
Console.WriteLine("value {0} is normal", value);
}
}
class c2: c1
{
public void fn2(int? value)
{
Console.WriteLine("value {0} is nullable", value);
}
}
class Program
{
static void Main(string[] args)
{
c1 o1 = new c1();
c2 o2 = new c2();
int val = 10;
o1.fn1(val);
o2.fn1(val);
o2.fn2(val);
Console.ReadLine();
}
}
结果是:
value 10 is normal.
value 10 is normal.
value 10 is nullable.
然而,c2具有函数fn2(int)。
答案 0 :(得分:2)
这是我在Jon Skeet博客上发现的。
继承可能会导致混乱的效果。当编译器去的时候 寻找实例方法重载,它考虑编译时 调用的“目标”的类,并查看声明的方法 那里。如果它找不到合适的东西,那么它会查看父级 上课......然后是祖父母班等。这意味着如果有的话 在层次结构的不同层次上的两种方法,“更深层次” 将被选中,即使它不是“更好的功能成员” 电话。
答案 1 :(得分:2)
在许多边缘情况下都是如此,没有神圣的“为什么”它,它只是如何编写C#规范。他们可以通过其他方式做到这一点,但决定这样做。 https://msdn.microsoft.com/en-us/library/aa691336(v=vs.71).aspx
最相关的部分(来自上面链接的C#规范的“7.4.2重载分辨率”,不同版本的规范在其他部分可能有相似的文字):
方法调用的候选集不包括...如果派生类中的任何方法适用,则基类中的方法不是候选
答案 2 :(得分:0)
就像说Handoko.Chen,在Jon Skeet的博客上我们可以找到
编译器会忽略子代中的重写方法。
所以我发现的唯一方法是隐藏继承方法:
class c2: c1 {
public void fn2(int? value) {
Console.WriteLine("value {0} is nullable", value);
}
public new void fn2(int value) {
base.fn2(value);
}
}