使用Interface作为List <t> </t>的参数

时间:2013-12-14 22:31:44

标签: c# entity-framework

我有一个类可以在一个构造函数中接受List<IMyInterface>作为参数

public class MyClass 
{
    public MyClass(List<IMyInterface> elements)
    {
    }
}  

并生成一个EF实体

public partial class MyEntity
{
    public string id {get;set;}
    . . . 
}

此类的扩展实现IMyInterfaseBool MyEntity及其扩展名在同一名称空间中)

public partial class MyEntity : IMyInterfase 
{
    public bool MyInterfaseImplementation {get;set;}
    .  .  .
} 

在我的视图模型构造函数

var x = from a in db.MyEntity
        select a;

如果我尝试使用a.ToList()作为我的课程的参数,则会抛出 InValid Arguments 错误

我在期待这个: 如果MyEntity实施IMyInterfase,那么MyClass必须接受它作为参数。

这种做法我错了吗?这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

您遇到此问题的原因是List<MyEntity>List<IMyInterface>不同。最简单的方法是将列表中的每个对象强制转换为IIMyInterface

var x = from a in db.MyEntity
        select a as IMyInterface;

这样x.ToList()将返回List<IMyInterface>而不是List<MyEntity>,您将能够将其传递给MyClass的构造函数。

修改

正如@Gert在评论中提到的,您需要修改您的查询,如下所示:

var x = (from a in db.MyEntity select a).AsEnumerable()
                                        .Cast<IMyInterface>()
                                        .ToList();

答案 1 :(得分:1)

鉴于IEnumerable<out T>T协变,您应该能够做到:

(from a in db.MyEntity
    select a).ToList<IMyInterface>()

请注意,List<T>本身协变(out上没有&#34; T&#34;修饰符。)

另一个解决方案是将构造函数中的参数更改为协变的内容,如IReadOnlyList<out T>,如:

public MyClass(IReadOnlyList<IMyInterface> elements)

当然,你只需要一个这两个解决方案。

答案 2 :(得分:0)

 var x = (from a in db.MyEntity
    select a).ToList();

 var c = new MyClass( x );

如果仍然无效,请尝试:

 var x = (from a in db.MyEntity
    select a).OfType<IMyInterface>().ToList();

我不确定List<T>是否有协变。