接口指定的属性的多态性

为什么这不起作用?

public class ClassOptions {} public interface Inode { ClassOptions Options {get;} } public class MyClass : Inode { public ClassOptions Options { get; set; } } public class ClassDerivedOptions : ClassOptions { } public class MyDerivedClass : Inode { public ClassDerivedOptions Options { get; set; } << does not implement INode... } 

[编译器消息告诉我为什么它会中断,但我想知道编译器为什么不通过它的原因 – 同样如果有任何解决方法? – 谢谢]

它不起作用,因为INode接口显式调用ClassOptions类型的Options属性。 C#不支持返回类型协方差(这是你在这种情况下要求的)。

对于它的价值,Microsoft Connect上还有一个语言function请求专门用于返回类型协方差:

需要使用C#/所有.NET语言的协变返回类型

如果您查看该页面,他们还会提到常见的解决方法是使用显式接口实现:

 public class MyDerivedClass : INode { public ClassDerivedOptions Options { get; set; } public ClassOptions INode.Options { get { return Options; } } } 

正如Justin所说,您想要的function称为“返回类型协方差”,它在C#中不受支持,或者就此而言,在CLR类型系统中不受支持。

虽然经常被要求,但这个function很快就会实现(*)。 由于CLR不支持它,为了实现它,我们只需生成所有为您进行呼叫转发的帮助方法。 由于您已经可以使用少量代码“手动”执行此操作,因此编译器为您执行此操作几乎没有增加任何附加值。 ( 正如今天的另一个问题所指出的,当编译器生成一种代表您进行接口转发的方法时,人们有时会感到困惑或烦恼 。)

别误会我的意思; 我可以看到它是如何派上用场的,我在C ++中使用了这个function。 但每次它都出现在C#程序中时,我发现我可以很容易地解决它的缺失问题。

(*)当然,五年前我会对命名参数和可选参数说完全一样的东西,现在它们已经在C#4中了。 可能实现一个不太可能的function,但需求必须相当大高。

它不起作用,因为接口定义了一个契约,当您实现此契约方法时,签名必须完全匹配。 可能的解决方法是使用通用接口:

 public class ClassOptions { } public class ClassDerivedOptions : ClassOptions { } public interface INode where T : ClassOptions { T Options { get; } } public class MyClass : INode { public ClassOptions Options { get; set; } } public class MyDerivedClass : INode { public ClassDerivedOptions Options { get; set; } } 

处理这种情况的标准方法是显式实现接口:

 public class MyDerivedClass : Inode { // New, more specific version: public ClassDerivedOptions Options { get; set; } // Explicit implementation of old, less specific version: ClassOptions Inode.Options { get { return Options; } } } 

这就是大多数旧的IList实现在generics之前的工作方式,例如:指定更具体的T this[int index]属性然后显式实现object IList.this[int index] ,在使用对象调用set时抛出exception错误的类型。

在您发布的示例代码中,您甚至不需要显式set ,因为它不是您的Inode接口的成员。