为什么在通用方法中强制转换为“ IEnumerable <T>”,但强制转换为“ List <T>”

时间:2019-11-18 00:40:32

标签: c# generics types casting

我敢肯定我错过了明显的答案,但是为什么这样做:

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>'.失败?两者都可能在运行时失败,并且都可能在运行时成功。什么语言规则支配着这个?

1 个答案:

答案 0 :(得分:0)

我认为这是以下问题的一个例子:
Cast List<T> to List<Interface>

我同意,在这种情况下,这似乎很奇怪,因为不可能从扩展字符串的内容中进行强制转换(字符串类是密封的),但是我猜测规则是您不能强制转换{ {1}}到List<T>,因为在T是扩展SomethingElse类或实现称为SomethingElse接口的类的情况下,可能会调用该方法。

例如:

List<SomethingElse>

因此,由于可以编写类似OtherMethod1的方法,而该方法在运行时会失败,因此编译器不允许出现这种情况。
尽管再次,密封类似乎是一个奇怪的情况,但如果微软愿意的话,可以允许这种情况。