C# CS0266有什么解决方法:无法隐式转换类型。。。(IList<;接口>;)?

C# CS0266有什么解决方法:无法隐式转换类型。。。(IList<;接口>;)?,c#,inheritance,interface,C#,Inheritance,Interface,我有一个实现接口的类。第二个类实现了第一个类的IList。我需要将第二个类分配给泛型属性,该属性是接口的IList 这是我使用的代码的演示: public class SODemo { public SODemo() { ClassWithIListOfClassWithInterface classWithIList = new ClassWithIListOfClassWithInterface(); IList<IDemoInterf

我有一个实现接口的类。第二个类实现了第一个类的IList。我需要将第二个类分配给泛型属性,该属性是接口的IList

这是我使用的代码的演示:

public class SODemo
{
    public SODemo()
    {
        ClassWithIListOfClassWithInterface classWithIList = new ClassWithIListOfClassWithInterface();

        IList<IDemoInterface> listOfInterfaces;

        // CS0266: Cannot implicitly convert type ...
        listOfInterfaces = classWithIList;
    }
}

public class ClassWithInterface : IDemoInterface
{
    // ...
}

public class ClassWithIListOfClassWithInterface : IList<ClassWithInterface>
{
    // ...
}

但是我在运行时得到一个
系统.InvalidCastException

问题不在于类本身,而在于
IList
IList
之间的转换

C中的IList被称为“T中的不变量”。这意味着您不能直接在
IList
IList
之间进行转换,即使它们具有继承关系

您可以做的是创建一个
IList
,并将源
IList
中的每个元素复制到它。当然,这相当麻烦,所以LINQ的做法是:

listOfInterfaces = classWithIList.Cast<IDemoInterface>().ToList();
listOfInterfaces=classWithIList.Cast().ToList();

问题不在于类本身,而在于
IList
IList
之间的转换

C中的IList被称为“T中的不变量”。这意味着您不能直接在
IList
IList
之间进行转换,即使它们具有继承关系

您可以做的是创建一个
IList
,并将源
IList
中的每个元素复制到它。当然,这相当麻烦,所以LINQ的做法是:

listOfInterfaces = classWithIList.Cast<IDemoInterface>().ToList();
listOfInterfaces=classWithIList.Cast().ToList();

如果需要更多信息,请查看。我还建议您使用
IEnumerable
而不是
IList
,因为它对LINQ更友好,它使对集合的评估变得懒惰,并且您的代码更通用。我知道问题的原因是什么。创建副本不是选项。请注意,这不会复制列表中的项目-它会创建一个引用相同项目的新列表(仅通过不同的界面)。如果需要更多信息,请签出。我还建议您使用
IEnumerable
而不是
IList
,因为它对LINQ更友好,它使对集合的评估变得懒惰,并且您的代码更通用。我知道问题的原因是什么。创建副本不是选项。请注意,这不会复制列表中的项目-它会创建一个引用相同项目的新列表(仅通过不同的界面)。是否可以对局部变量使用
IEnumerable
而不是
ILIst
。。。出于性能原因,我需要List(),这样就不能使用更通用的变量了。基础列表将更加具体,并可能导致运行时错误(例如,试图将
ClassWithInterface2
添加到
列表
)。变量类型只是告诉编译器允许对基础对象执行哪些操作。@DStanley谢谢您的提示。这听起来令人不安。你有一个具体的例子吗?我不确定你的意思-一个
列表
不是一个
IList
,因为你不能向它添加
Apple
。因此,在您的情况下,您不能使用更通用的变量来引用更具体的集合。是否可以对局部变量使用
IEnumerable
而不是
ILIst
。。。出于性能原因,我需要List(),这样就不能使用更通用的变量了。基础列表将更加具体,并可能导致运行时错误(例如,试图将
ClassWithInterface2
添加到
列表
)。变量类型只是告诉编译器允许对基础对象执行哪些操作。@DStanley谢谢您的提示。这听起来令人不安。你有一个具体的例子吗?我不确定你的意思-一个
列表
不是一个
IList
,因为你不能向它添加
Apple
。因此,在您的情况下,不能使用更通用的变量来引用更具体的集合。