解决接口中的歧义,该接口扩展了具有相同名称的方法的另外两个接口

本文关键字:接口 方法 两个 歧义 扩展 解决 | 更新日期: 2023-09-27 18:24:35

如果我有接口:

public interface ANewThing { IKey Key { get; } }
public interface AnOldThing { object Key{ get; } }
public interface ACompositeThing : ANewThing , AnOldThing  { }

我写这个:

ACompositeThing compositeThing = GetCompositeThing();  
Trace.WriteLine(compositeThing.Key);

它不编译,抱怨对Key的调用不明确(如果Key属性返回的类型相同,则没有任何区别)。我知道在实现ACompositeThing的类中,我可以显式地实现接口ANewThingAnOldThing,但当我有不知道具体实现的方法,只知道它们将被赋予ACompositeThing时,这对我没有帮助。

所以我的问题是:

我可以在ACompositeThing接口中做些什么来说明应该如何解决Key属性的模糊性吗?

比如说"当通过此接口访问Key属性时,始终从ANewThing实现返回Key属性"?

还是我必须接受我不能这样做,并且在访问之前必须始终将我的ACompositeThing强制转换到其他接口之一?

解决接口中的歧义,该接口扩展了具有相同名称的方法的另外两个接口

这很糟糕,但您可以在ACompositeThing:中声明另一个成员

public interface ACompositeThing : ANewThing , AnOldThing {
    new IKey Key { get; }
}

现在,从调用者的角度来看,这将是首选项。然而,这意味着现在可能有三个不同的实现,并且任何为ANewThing.Key使用显式接口实现的ACompositeThing实现都将要么必须更改以公开成员,要么添加一个新成员以实现ACompositeThing.Key

当然,如果可能可以,您应该避免这种情况,或者在非常有限的时间内仅在从旧接口到新接口的转换中使用它。

与其说是一个答案,不如说是一种变通方法:使ACompositeThing成为显式实现Key属性的基类(而不是接口)。

我可以在ACompositeThing接口中做些什么来说明应该如何解决Key属性的模糊性吗?

比如说"当通过这个接口访问Key属性时,总是从ANewThing实现返回Key属性"?

试试这个代码:

ANewThing newThing = GetCompositeThing();  
Trace.WriteLine(newThing.Key);

ACompositeThing compositeThing = GetCompositeThing();  
Trace.WriteLine(((ANewThing)compositeThing).Key);

这是一个被称为"钻石问题"或"钻石继承"的经典问题。在大多数情况下,它源于糟糕的OOP设计或糟糕的命名约定。我想这也是你的问题。

试着在谷歌上搜索一下"钻石问题",有各种各样的解决方案。

相关文章: