C# 无法转换源类型';列表<;人>';到IList<;等轴物>;

C# 无法转换源类型';列表<;人>';到IList<;等轴物>;,c#,.net,casting,C#,.net,Casting,这可能是一个非常简单的问题,但有些事情对我来说没有意义 鉴于这一类别: public class Person : ICloneable { public object Clone() { Console.WriteLine("Hello, world"); return new Person(); } } 为什么这样可以 List<Person> people = new List<Person> { new P

这可能是一个非常简单的问题,但有些事情对我来说没有意义

鉴于这一类别:

public class Person : ICloneable {
    public object Clone()
    {
        Console.WriteLine("Hello, world");
        return new Person();
    }
}
为什么这样可以

List<Person> people = new List<Person> { new Person() };

IEnumerable<ICloneable> clonables = people;
List people=newlist{new Person()};
IEnumerable clonables=人;
但这不是吗

List<Person> people = new List<Person> { new Person() };

IList<ICloneable> clonables = people;
List people=newlist{new Person()};
IList clonables=人;

为什么我可以分配给IEnumerable IClonable,但不能分配给IList IClonable?

我有一个不同的答案,这是错误的。我道歉。谢谢马特指出这一点

这个错误消息很容易引起误解。这意味着演员阵容会起作用,但不会。问题在于,将Person转换为iClonable可能需要调整指针,以便虚拟函数表适用于通用iClonable。这意味着列表中的每个元素都可能需要调整。真正的解决方法是使用ToList:

        IList<ICloneable> clonablesA = people.ToList<ICloneable>();
IList clonablesA=people.ToList();
忽略下面的一些评论,因为我完全删除了我的第一个答案。

:

公共接口IList:ICollection,
IEnumerable,IEnumerable
:

公共接口IEnumerable:IEnumerable
请注意
out
in
IEnumerable
<代码>IEnumerable是

这称为协方差。埃里克·利珀特(Eric Lippert)和乔恩·斯基特(Jon Skeet)(以及其他人)在回答这个问题时对协方差(及其孪生变量,逆变)给出了一些很好的解释:


基本上,您可以枚举
人的列表
,就像您可以枚举
可克隆的人的列表一样,不会出现任何问题,因为您无法更改枚举。但是您不能将您的
Person
列表分配给
ICloneable
列表,因为您可以稍后尝试在其中插入
ICloneable
的其他派生词,这将导致严重违反类型安全性。

您收到的错误消息可能已经告诉您原因。
IEnumererable
是协变的,这就是它工作的原因<代码>列表不是,也不能是。因此,解决方案是:
cloneables=people.Cast().ToList()不是一个好的解决方案。你实际上是在创建一个新的
列表,而不是重新分配旧列表。不要在帖子上签名。它们已经签署;请参阅?----------->即使是明确的演员阵容也不起作用。IList克隆人=(IList)人;错误消息没有说明显式强制转换存在,也没有在此上下文中有效。使用VS 2013,我看到的错误消息是:错误1无法将类型“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.IList”。存在显式转换(是否缺少转换?)C:\Users\Ken\Documents\Visual Studio 2013\Projects\Samples\Cloneable\Cloneable\Program。cs 29 45 Cloneable显式转换无法工作。它将用编译时错误换取运行时异常(
InvalidCastException
)。
public interface IList<T> : ICollection<T>, 
    IEnumerable<T>, IEnumerable
public interface IEnumerable<out T> : IEnumerable