[英]Derived method stronger than override in c#?
( 再次烦人的问题...... )
之前问过这个 - (这部分与我的问题有关) - 我得到了一个答案:
参见C#4规范的§7.6.5.1:
候选方法集合被简化为仅包含来自大多数派生类型的方法:对于集合中的每个方法CF,其中C是声明方法F的类型,所有在基本类型C中声明的方法都从集合。
好。
我有这个代码: .Dump() is like a WriteLine command...
public class Base
{
public void Foo(string strings) { "1".Dump();}
public virtual void Foo(object strings) { "2".Dump();}
}
public class Child : Base
{
public override void Foo(object strings) { "4".Dump();}
}
但是这段代码:
Child c = new Child();
c.Foo("d");
发出: "1"
可是等等 ...
我们不是说is reduced to contain only methods from the most derived types:
Child从其父public void Foo(string strings)
和NEARER覆盖函数中有1个函数 。
那他为什么选择它的基地功能呢? 继承的函数是否比覆盖更复杂?
是否与覆盖在运行时有关?
请帮助。
这种情况怎么样?
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
}
public class Child : Base
{
public override void Foo(int x) { "2".Dump();}
public void Foo(object x) { "3".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(6); //emits "3"
}
那是因为你的孩子拿走了一个物体。
public class Child : Base
{
public override void Foo(object strings) { "4".Dump();}
}
使它成为字符串,然后将调用其中一个。
public class Child : Base
{
public override void Foo(string strings) { "4".Dump();}
}
为什么这个?
因为编译器看到子进程有object
所以它必须转换为string
而在基类中它可以作为字符串使用。
所以它称之为基础。
虽然重写功能在子类中更接近。 但是这里的规则在孩子和基础上是不同的。 孩子有对象,基础有字符串。 如果两者都有object
或者两者都有string.
这是公平的string.
这里有两个概念混淆,重载和覆盖。 重载是为同名函数提供多个签名并根据该签名选择一个进行调用的概念 。 覆盖是在派生类中重新定义方法的概念。
子类是否覆盖其中一个方法定义与调用哪个函数完全无关,因为它不会更改任一方法的签名。 根据定义和构造覆盖方法不能改变它的签名 。
因此,如果签名未更改,则基于签名确定正确调用函数的相同机制将用于父类和子类。
更新
事实上,Eric Lippert在他的博客中指出,它还有一点点。 事实证明,如果有一个方法匹配子类中的重载 ,它将不会在基类中查找任何方法。 原因是理智的 - 避免破坏变化 - 但是当你拥有基础和子类时,结果有点不合逻辑。
我只能回应Jon Skeet:“鉴于这种奇怪,我的建议是避免跨越继承边界的重载......至少对于如果平铺层次结构,多个方法可适用于给定调用的方法”
你看这里最好的比赛规则 。
您将类似参数的string
传递给Foo(..)
函数。
基类有一个Foo(string..)
,而Child类则没有 。 因此,在这种情况下,最终选择基本方法。
我认为基于它的dataType
选择了基类方法
作为c.Foo("d");
与基类方法完全匹配,并且在derived class
没有为它重写任何方法,因此调用基类方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.