代码之家  ›  专栏  ›  技术社区  ›  V0ldek

为什么在泛型方法中允许对“IEnumerable<T>`进行强制转换,而对“List<T>`进行强制转换?”

  •  0
  • V0ldek  · 技术社区  · 5 年前

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

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

    0 回复  |  直到 5 年前
        1
  •  0
  •   Ross Gurbutt    5 年前

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

    我同意在这种情况下这看起来很奇怪,因为它不可能从扩展string的东西(string类是密封的)进行转换,但是我猜规则是不能转换的 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这样在运行时失败的方法,编译器不允许整个场景。