继承具有精炼返回类型的接口

时间:2014-12-12 11:18:15

标签: c# inheritance

如果我有

interface Parent{}
interface Child : Parent {}
interface MyInterface {
  Parent P {get;}
}

为什么不

class MyClass : MyInterface {
  public Child P {get; }
}

typecheck,但是

class MyClass : MyInterface {
  private Child C {get; set;}
  public Parent P {get { return C; }}
}

确实

两种方法是否有任何行为可以表现出明显不同的行为(减去额外的空检查会在尝试强制转换之前使代码混乱)?

我可以使用泛型,并使用

interface MyInterface<T> where T : Parent {
  T P {get;}
}

class MyClass : MyInterface<Child> {
  Child P {get;}
}

但是我觉得这会是一个黑客攻击,因为它会混淆接口的定义,它必须由所有继承者显式设置,并将继承者重新调整为单个子类型,看起来收益很少。

1 个答案:

答案 0 :(得分:4)

回答你的问题:

  

为什么没有[x]类型检查,但是[y]呢?

仅仅因为C#(和CLR)don't support return type covariance。 (Eric Lippert是你能得到答案的最佳来源,例如&#34;为什么C#不做X?&#34;)

  

这两种行为有什么办法可以表现出明显不同的行为吗?

没有。你认为这个 符合合同是正确的。

返回Child的属性getter理论上符合&#34;返回Parent&#34;合同。

然而,事实仍然是C#(和CLR)不支持这一点。你知道它符合&#34;返回Parent&#34;合同,但你不能告诉C#。


作为第二个示例的替代实现,您可以使用显式接口实现

class MyClass : MyInterface
{
    Parent MyInterface.P { get { return this.P; } }
    public Child P { get; set; }
}

像这样实施,

  • 每当您使用MyClass的实例时,您看到并可以使用的合同是它可以接受或返回Child
  • 每当您将该实例投射到MyInterface时,您可以看到和使用的合同只是它可以返回Parent

编辑:如果P实际上是一个明智的属性名称(这对于界面中的Parent属性和Child都有意义,那么这对您的工作示例有什么影响?在实现中的属性),你可以将它用于两者。