【发布时间】:2019-11-18 00:40:32
【问题描述】:
我很确定我错过了明显的答案,但为什么会这样:
public static void Foo(IEnumerable<string> strings) { }
public static void Bar<T>(IEnumerable<T> ts)
{
Foo((IEnumerable<string>)ts);
}
是允许的,而这个:
public static void Foo(List<string> strings) { }
public static void Bar<T>(List<T> ts)
{
Foo((List<string>)ts);
}
CS0030 Cannot convert type 'System.Collections.Generic<T>' to type 'System.Collections.Generic<string>'. 失败?两者都有可能在运行时失败,并且都有可能在运行时成功。这是什么语言规则?
【问题讨论】:
-
这能回答你的问题吗? Why can't I cast from a List<MyClass> to List<object>? 尤其是声明说:“这是安全的,因为
IEnumerable<T>没有公开任何接受 T 的方法。” -
@BagusTesa 特别是 T 被定义为 out 仅用于 IEnumerable ,它强制您声明 IEnumerable
不接受任何类型的 T -
不,它没有,“重复”问题似乎也没有。我知道什么是通用方差,但是允许从
IEnumerable<T>到IEnumerable<string>任意T的转换是不安全的。IEnumerable<T>必须是协变和逆变的,才能在运行时永远不会失败。