在派生接口中隐藏接口成员

Hiding interface-member in derived interface

我刚刚反编译了一些 3rd-party 接口并且对以下内容感到困惑:

public interface IFoo 
{
    string Name { get; set; }
}
public interface IBar : IFoo
{
    new string Name { get; set; }
}

如您所见,我有两个接口,其中 IBar 通过隐藏其 Name-属性 扩展了 IFoo。但是我看不到 new-关键字在这里做什么。我读到 an answer from Eric Lippert 与仅在 return 类型上不同的成员有关。但是在我的例子中,一切都只是一个字符串。

当然,我们可以明确地实现其中一个接口。但无论如何,如果没有 new ,那也是可能的。

接口没有继承或覆盖某些东西的想法。您在这里使用 "new" 避免的只是名称冲突。您实现了一个新的 属性,顺便说一句,名称相同。 其他一切都会像往常一样工作。

在 class 上实现 IBar 时,您可以定义 public 属性,这将用作两个 Name 属性。隐式定义接口的算法从接口的角度工作。 C# 编译器为 IFoo 搜索 属性 名称 'Name',然后再次搜索 IBar,然后突然为两者找到相同的 属性。

或者,您可以显式声明接口成员,如果愿意,您可以附加 'Name' 的两个不同实现。

这也解释了为什么你总是必须用它的定义类型来命名显式定义。您必须显式实现 IFoo.Name 和 IBar.Name,它不会以任何方式隐藏,它可以从外部访问,具体取决于您使用的是什么 Cast 到什么接口。这就像你在两个不同的命名空间中定义 a class "Name" 一样,这里的想法相同。

你不太可能在 VB.Net 中提出这个问题,因为每个接口实现都是显式的。

IFoo和IBar中的Name字段不同,可以在一个class中实现两个Name:

public interface IFoo
{
    string Name { get; set; }
}
public interface IBar : IFoo
{
    new string Name { get; set; }
}

public class Implementation : IBar
{
    string IBar.Name { get; set; } = "Bar";

    string IFoo.Name { get; set; } = "Foo";
}

如果将 Implementation class 转换为 IBar,则值为 Bar,如果将其转换为 IFoo,则值为 Foo。