我已经指定了几个接口,我使用Entity Framework 4实现了实体.我能想到的最简单的演示代码是:
public class ConcreteContainer : IContainer
{
public EntityCollection<ConcreteChild> Children { get; set; }
}
public class ConcreteChild : IChild
{
}
public interface IContainer
{
IEnumerable<IChild> Children { get; set; }
}
public interface IChild
{
}
Run Code Online (Sandbox Code Playgroud)
我从上面收到以下编译器错误:
'Demo.ConcreteContainer'没有实现接口成员'Demo.IContainer.Children'.'Demo.ConcreteContainer.Children'无法实现'Demo.IContainer.Children',因为它没有匹配的返回类型'System.Collections.Generic.IEnumerable'
我目前的理解是,这是因为IEnumerable(由EntityCollection实现)是协变的,但可能不是逆变的:
此类型参数是协变的.也就是说,您可以使用指定的类型或更多派生的类型.有关协方差和逆变的更多信息,请参阅泛型中的协方差和逆变.
我是否正确,如果是这样,有什么方法可以实现我的目标,IContainer纯粹根据其他接口而不是使用具体类来指定接口?
或者,我是否误解了一些更基本的东西?
.NET 4中的泛型差异在这里无关紧要.接口的实现必须在类型方面完全匹配接口签名.
例如,take ICloneable,看起来像这样:
public interface ICloneable
{
object Clone();
}
Run Code Online (Sandbox Code Playgroud)
能够像这样实现它会很好:
public class Banana : ICloneable
{
public Banana Clone() // Fails: this doesn't implement the interface
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
...但.NET不允许这样做.您有时可以使用显式接口实现来解决此问题,如下所示:
public class Banana : ICloneable
{
public Banana Clone()
{
...
}
object ICloneable.Clone()
{
return Clone(); // Delegate to the more strongly-typed method
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在你的情况下,你不能这样做.请考虑以下代码,如果ConcreteContainer考虑实现,则该代码有效IContainer:
IContainer foo = new ConcreteContainer();
foo.Children = new List<IChild>();
Run Code Online (Sandbox Code Playgroud)
现在你的属性设置器实际上只是声明可以使用EntityCollection<ConcreteChild>,所以它显然不能用于任何 IEnumerable<IChild> - 违反接口.
| 归档时间: |
|
| 查看次数: |
1072 次 |
| 最近记录: |