c# - 逆变和 Entity Framework 4.0 : how to specify EntityCollection as IEnumerable?

标签 c# covariance

我已经指定了几个接口(interface),我正在使用 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
{        
}

我从上面收到以下编译器错误:

'Demo.ConcreteContainer' does not implement interface member 'Demo.IContainer.Children'. 'Demo.ConcreteContainer.Children' cannot implement 'Demo.IContainer.Children' because it does not have the matching return type of 'System.Collections.Generic.IEnumerable'

我目前的理解是,这是因为IEnumerable (由 EntityCollection 实现)是协变的,但可能不是逆变的:

This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.

我是否正确?如果正确,是否有任何方法可以实现我的目标,即纯粹根据其他接口(interface)而不是使用具体类来指定 IContainer 接口(interface)?

或者,我是否误解了一些更基本的东西?

最佳答案

.NET 4 中的通用变体在这里无关紧要。接口(interface)的实现必须在类型方面完全匹配接口(interface)签名。

例如,取 ICloneable ,看起来像这样:

public interface ICloneable
{
    object Clone();
}

能够像这样实现它会是nice:

public class Banana : ICloneable
{
    public Banana Clone() // Fails: this doesn't implement the interface
    {
        ...
    }
}

...但是.NET 不允许这样做。您有时可以使用显式接口(interface)实现来解决这个问题,如下所示:

public class Banana : ICloneable
{
    public Banana Clone()
    {
        ...
    }

    object ICloneable.Clone()
    {
        return Clone(); // Delegate to the more strongly-typed method
    }
}

但是,在您的情况下,您永远无法做到这一点。考虑以下代码,如果 ConcreteContainer 则该代码有效被认为实现IContainer :

IContainer foo = new ConcreteContainer();
foo.Children = new List<IChild>();

现在您的属性 setter 实际上只声明为与 EntityCollection<ConcreteChild> 一起使用, 所以它显然不能与 any 一起使用 IEnumerable<IChild> - 违反接口(interface)。

关于c# - 逆变和 Entity Framework 4.0 : how to specify EntityCollection as IEnumerable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2369071/

相关文章:

c# - 如何根据按钮点击设置Label的内容

c# - 为什么将 MemberInfo.GetCustomAttributes(Type) 定义为返回属性数组?

c# - Windows 窗体加事件目录

c# - 没有返回类型协变的接口(interface)继承

c# - 如何在 SqlDataSource 中使用 appSettings 键

c# - 如何将自定义 GUI 组件添加到 ToolBox

c# - 为什么我不能从 List<MyClass> 转换为 List<object>?

python - 我想找到 pandas 数据框中 1 列与所有其他列之间的协方差

c# - 现实世界的数组协方差问题

c# - 有没有办法确定 C# 4.0 中接口(interface)/委托(delegate)的方差?