为什么强制转换为`IEnumerable<T>`允许,但限于`List<T>`在通用方法中



我很确定我错过了显而易见的答案,但为什么是:

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

我认为这是以下问题的一个边缘情况示例:
Cast List<T>到列表<界面>

我同意在这种情况下,这看起来很奇怪,因为不可能从扩展字符串的东西(字符串类是密封的(进行强制转换,但我猜规则只是不能将List<T>强制转换为List<SomethingElse>,因为在t是扩展类SomethingElse或实现名为SomethingElse的接口的类的情况下,可能会调用该方法。

例如:

public static void Foo(List<string> strings) { }
public static void Bar<T>(List<T> ts)
{
Foo((List<MyInterface>)ts);
}
public static void OtherMethod1()
{
Bar<MyClass>(new List<MyClass>)
}
public static void OtherMethod2()
{
Bar<MyInterface>(new List<MyInterface>)
}
public classs MyClass : MyInterface
{
}

因此,因为有可能编写像OtherMethod1这样在运行时失败的方法,所以编译器不允许整个场景
尽管如此,密封类似乎是一个奇怪的边缘案例,如果微软愿意的话,它可能会被允许。