仅在 3.5 中从 List<T> 到 IEnumerable<T> 的 InvalidCastException
InvalidCastException from List<T> to IEnumerable<T> only in 3.5
如果我这样称呼
var list = new List<Class1>();
Test((IEnumerable<Interface1>)list);
和
public interface Interface1
{
}
public static void Test(IEnumerable<Interface1> test)
{
}
public class Class1 : Interface1
{
}
我在 3.5 框架中遇到 InvalidCastException,但在 4 和 4.5 中没问题。而且我不明白为什么,两者都有 IEnumerable
如果我检查 3.5 和 4.5 中的列表,我不明白为什么会收到 InvalidCastException
4.5:
public class List<T> : IList<T>, ICollection<T>,
IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>
3.5:
public class List<T> : IList<T>, ICollection<T>,
IEnumerable<T>, IList, ICollection, IEnumerable
在 3.5 中,IEnumerable<T>
接口不是协变的。这是在 4.0 中添加的。
需要协方差才能转换为更派生的类型,这里就是这种情况(List<T>
实现 IEnumerable<T>
)。
您假设 IEnumerable<T>
是协变的,这在 .NET 4.0 中才成立。在旧版本中,它不是协变的(因为该语言不支持该功能)。
这是因为在 3.5 中 IEnumerable<T>
被声明为
public interface IEnumerable<T> : IEnumerable
但在 4.0 及更新版本中它被声明为
public interface IEnumerable<out T> : IEnumerable
out
允许 covariance,这是您需要从 List<Class1>();
到 IEnumerable<Interface1>
在 3.5 中你只能做 List<Class1>();
到 IEnumerable<Class1>
或 List<Interface1>();
到 IEnumerable<Interface1>
作为 3.5 中的解决方法,您可以使用 Cast<T>()
LINQ 方法完成您想要的。
var list = new List<Class1>();
Test(list.Cast<Interface1>());
如果我这样称呼
var list = new List<Class1>();
Test((IEnumerable<Interface1>)list);
和
public interface Interface1
{
}
public static void Test(IEnumerable<Interface1> test)
{
}
public class Class1 : Interface1
{
}
我在 3.5 框架中遇到 InvalidCastException,但在 4 和 4.5 中没问题。而且我不明白为什么,两者都有 IEnumerable
如果我检查 3.5 和 4.5 中的列表,我不明白为什么会收到 InvalidCastException
4.5:
public class List<T> : IList<T>, ICollection<T>,
IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>
3.5:
public class List<T> : IList<T>, ICollection<T>,
IEnumerable<T>, IList, ICollection, IEnumerable
在 3.5 中,IEnumerable<T>
接口不是协变的。这是在 4.0 中添加的。
需要协方差才能转换为更派生的类型,这里就是这种情况(List<T>
实现 IEnumerable<T>
)。
您假设 IEnumerable<T>
是协变的,这在 .NET 4.0 中才成立。在旧版本中,它不是协变的(因为该语言不支持该功能)。
这是因为在 3.5 中 IEnumerable<T>
被声明为
public interface IEnumerable<T> : IEnumerable
但在 4.0 及更新版本中它被声明为
public interface IEnumerable<out T> : IEnumerable
out
允许 covariance,这是您需要从 List<Class1>();
到 IEnumerable<Interface1>
在 3.5 中你只能做 List<Class1>();
到 IEnumerable<Class1>
或 List<Interface1>();
到 IEnumerable<Interface1>
作为 3.5 中的解决方法,您可以使用 Cast<T>()
LINQ 方法完成您想要的。
var list = new List<Class1>();
Test(list.Cast<Interface1>());