Roy*_*mir 7 .net c# clr .net-4.0
它说 :
如果在层次结构的不同级别有两种方法,则首先选择"更深"的方法,即使它不是呼叫的"更好的功能成员".
还 -
事实证明,如果您覆盖子类中的基类方法,则不会将其视为声明它.
现在让我们回到我的问题:
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
}
public class Child : Base
{
public void Foo(object x) { "3".Dump();}
public override void Foo(int x) { "2".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(10); //emits 3
}
Run Code Online (Sandbox Code Playgroud)
好的.根据文章
首先选择"更深"的一个,即使它不是一个"更好的功能.它不计算覆盖...
所以它是正确的,程序发出"3".(Foo(object x)被执行)
让我们改变1行的顺序:
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
public void Foo(object x) { "3".Dump();} //<line being moved here
}
public class Child : Base
{
public override void Foo(int x) { "2".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(10); //emits 2 !!!!
}
Run Code Online (Sandbox Code Playgroud)
现在它发出"2".
现在让我们将所有int更改为object,将所有对象更改为int:
public class Base
{
public virtual void Foo(object x) { "1".Dump();}
public void Foo(int x) { "3".Dump();}
}
public class Child : Base
{
public override void Foo(object x) { "2".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(1); //emits "3"
}
Run Code Online (Sandbox Code Playgroud)
问题:
问题#1:在案例2中,Child 继承了 Foo(object x)其父亲并且他也覆盖了一个方法.
但我们不是这么说的:
事实证明,如果您覆盖子类中的基类方法,则不会将其视为声明它
???
事实上,我们还没有宣布继承的功能......所以这种情况下的规则是什么?
问题#2:在案例3中,Child 继承了 Foo(int x)其父亲并且他也覆盖了一个方法.
但现在,他选择了父亲的功能......
它似乎override只有在完全匹配时才会获胜.
再次,这种情况下的规则是什么?
请参阅类型 T 中名称 N 的成员查找过程Foo(在您的情况下是类型中的成员Child):
首先,构造 T 中声明的名为 N 的所有可访问(第 3.5 节)成员和 T 的基本类型(第 7.3.1 节)的集合:
virtual void Foo(int x) // Base
void Foo(object x) // Base
override void Foo(int x) // Child
Run Code Online (Sandbox Code Playgroud)
包含 override 修饰符的声明被排除在该集合之外。
virtual void Foo(int x) // Base
void Foo(object x) // Base
Run Code Online (Sandbox Code Playgroud)
参数具有整数类型。所以,这里最好的选择是(参数类型与参数类型匹配)
virtual void Foo(int x) // Base
Run Code Online (Sandbox Code Playgroud)
并且调用了这个方法。但它是虚方法。其调用是由于虚方法调用机制:
对于类中声明或继承的每个虚拟方法,都存在该方法相对于该类的最派生实现。虚拟方法 M 相对于类 R 的最派生实现确定如下:
- 如果 R 包含 M 的引入虚拟声明,那么这是 M 的最派生实现。
- 否则,如果 R 包含 M 的重写,那么这是 M 的最派生的实现。
- 否则,M 相对于 R 的最派生实现与 M 相对于 R 的直接基类的最派生实现相同。
virtual void Foo(int x)相对于类而言,方法的最派生实现是什么Child?是的
override void Foo(int x) // Child
Run Code Online (Sandbox Code Playgroud)
哪个被调用。相同的规则适用于您的第三个示例。但是,当删除重写方法后剩下两个选项时,最佳选择(由于参数类型)是非虚拟方法。