这个问题在这里已经有了答案:
base class implementing base interface while derived/concrete class implementing extended interface, why?
(1 个回答)
2年前关闭。
为什么这个程序打印“子名”而不是“基本名”?
using System;
class Program
{
static void Main(string[] args)
{
var child = new Child();
Console.WriteLine(((INamedObject)child).Name);
Console.ReadLine();
}
}
interface INamedObject
{
string Name { get; }
}
class Base : INamedObject
{
string INamedObject.Name
{
get
{
return "Base Name";
}
}
}
class Child : Base, INamedObject
{
public string Name
{
get
{
return "Child Name";
}
}
}
我希望当我将 child 转换为 INamedObject 时,将调用 INamedObject 显式实现的 Name 属性。但是发生的是调用了 Child.Name 属性。
为什么当我这样声明 Child 类时(从 Child 中删除 INamedObject):
class Child : Base
{
public string Name
{
get
{
return "Child Name";
}
}
}
它开始打印“基本名称”?
最佳答案
其他答案没有正确识别您偶然发现的 C# 功能。
您发现了 C# 的一个有点令人困惑的特性,称为“接口(interface)重新实现”。规则是,当派生类专门重新声明已由基类实现的接口(interface)时,编译器会重新开始并从头开始重新进行接口(interface)映射。
如果发生这种情况,则派生类型较多的方法优先于派生类型较少的方法,因为我们假设开发更多派生类型的开发人员比开发基类版本的开发人员具有更好的实现。毕竟,如果派生版本更糟糕,开发人员就不会实现它!
此规则允许您决定是否希望派生类替换基类接口(interface)映射,因为有时您想要,有时您不想。
有关更多详细信息,请参阅我 2011 年有关此功能的文章:
https://blogs.msdn.microsoft.com/ericlippert/2011/12/08/so-many-interfaces-part-two/
您可能还会发现此答案很有帮助:
Abstract base classes that implement an interface
有关描述此语言功能的规范部分,请参阅
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/interfaces#interface-re-implementation
关于c# - 为什么显式接口(interface)实现以这种方式工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59092900/