【问题标题】:Hiding interface-member in derived interface在派生接口中隐藏接口成员
【发布时间】:2019-12-02 08:44:35
【问题描述】:

我刚刚反编译了一些 3rd-party 界面,并对以下内容摸不着头脑:

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

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

当然,我们可以显式地实现任何一个接口。但无论如何,如果没有new,这将是可能的。

【问题讨论】:

  • 我认为这里的new 只是表明NameIBar 中的功能与IFoo 中的实现是不同的,并且不同 .您实质上是在声明 IBar.Name 没有实现或替换 IFoo.Name - 它是对它的补充,只是 碰巧 共享相同的名称
  • 返回类型不同的成员是这种模式的常见原因。您在这里介绍的界面模式没有多大意义;你能详细说说你发现这个模式在哪里使用,它的用途是什么?
  • @EricLippert 我无权访问源代码。我得到的只是 ArcObjects 的公共接口。原始方法的名称不同,但是两个版本都返回 string

标签: c# interface member-hiding


【解决方案1】:

接口没有继承或覆盖某些东西的想法。您在这里使用“新”避免的只是名称冲突。你实现了一个新的属性,顺便提一下同名。 其他一切都会照常工作。

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

您也可以显式声明接口成员,如果您愿意,可以附加两个不同的“名称”实现。

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

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

【讨论】:

    【解决方案2】:

    IFoo和IBar中的Name字段不同,可以在一个类中实现两个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 类转换为 IBar,则值为 Bar,如果将其转换为 IFoo,则值为 Foo。

    【讨论】:

      猜你喜欢
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-20
      • 2011-07-14
      • 2018-08-09
      • 2010-12-19
      • 2011-04-03
      相关资源
      最近更新 更多