解决“最派生的"问题.虚拟替代中的方法 [英] Resolving the "most derived" method in a virtual override
问题描述
我有一个简单的基类和派生类:
I have a simple base class and derived class:
class Base
{
public virtual void Write(int value)
{
Console.WriteLine("base int: {0}", value);
}
public virtual void Write(string value)
{
Console.WriteLine("base string: {0}", value);
}
}
class Derived : Base
{
public override void Write(int value)
{
Console.WriteLine("derived int: {0}", value);
}
public virtual void Write(IEnumerable enumerable)
{
Console.WriteLine("derived IEnumerable: {0}", enumerable);
}
public virtual void Write(object o)
{
Console.WriteLine("derived obj: {0}", o);
}
}
如果我运行此命令:
static void Main(string[] args)
{
Derived d = new Derived();
Console.WriteLine("derived:");
d.Write(42);
d.Write("hello");
Console.WriteLine("base:");
Base b = d;
b.Write(42);
b.Write("hello");
}
我得到:
derived:
derived obj: 42
derived IEnumerable: hello
base:
derived int: 42
base string: hello
但是我期望"b.Write(42)"和"d.Write(42)"是相同的.字符串大小写相同.
But I am expecting "b.Write(42)" and "d.Write(42)" to be identical. The same for the string case.
我不明白什么?在无法修改基本"的约束下,如何使行为达到预期?
What am I not understanding? How can I get the behavior to be what I am expecting given the constraint that I cannot modify "Base"?
更新:请参见 Eric的发布.
推荐答案
之所以会发生这种情况,是因为C#首先考虑以类型声明的方法,包括替代方法.请参阅: C#规范的7.3节.
This happens because C# considers methods declared in a type before anything else, including override methods. See: Section 7.3 of the C# spec.
此博客帖子很好地说明了这一点,并说明原因.
This blog post explains it pretty well, and also explains the reasons.
以下两个规则证明了这种高度非直觉的行为是正确的:
This highly unintuitive behavior is justified by the following two rules:
- 是否重写方法是实现的详细信息 应该被允许改变 不破坏客户代码.
- 更改为不会破坏继承类的基类 不破坏继承的客户 课.
- Whether or not a method is overridden is an implementation detail that should be allowed to change without breaking client code.
- Changes to a base class that don't break an inherited class should not break clients of the inherited class.
这篇关于解决“最派生的"问题.虚拟替代中的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!