【问题标题】:Why can't I assign List<int> to IEnumerable<object> in .NET 4.0为什么我不能在 .NET 4.0 中将 List<int> 分配给 IEnumerable<object>
【发布时间】:2022-04-22 03:53:12
【问题描述】:

我尝试这样做:

IEnumerable<object> ids = new List<string>() { "0001", "0002", "0003" };

效果很好!

但是当我尝试这样做时:

IEnumerable<object> intIds = new List<System.Int32>() { 1, 2, 3 };

Visual Studio 告诉我: 无法将类型“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.IEnumerable”。存在显式转换(您是否缺少演员表?)

这是为什么呢?

【问题讨论】:

    标签: .net-4.0 ienumerable covariance value-type


    【解决方案1】:

    简单地说:.NET 4 中的泛型变体不支持作为值类型的类型参数的变体。

    它可以用于引用类型的原因是,一旦 CLR 确定它知道泛型转换是安全的,它就可以以相同的方式处理所有引用值 - 它们在内部具有相同的表示。将string 引用转换为object 引用不需要实际 转换,反之亦然,如果您知道它绝对是对字符串的引用 - 基本上是相同的位。因此,生成的本机代码可以将引用视为引用,很高兴知道有关方差的规则已经保证在类型安全级别上不会发生任何令人讨厌的事情,并且不对值本身执行任何转换。

    对于值类型,不是,对于转换不是“引用转换”(即保留表示的转换)的引用类型,。这就是为什么你不能顺便写IEnumerable&lt;XName&gt; names = new List&lt;string&gt;();...

    【讨论】:

      【解决方案2】:

      来自MSDN Blogs > C# Frequently Asked Questions > Covariance and Contravariance FAQ

      仅当类型参数是引用类型时才支持变体。值类型不支持方差。 以下内容也无法编译:

      // int is a value type, so the code doesn't compile.
      IEnumerable<Object> objects = new List<int>(); // Compiler error here.
      

      【讨论】:

        【解决方案3】:

        另一种解决方案是使用扩展方法 Enumerable.Cast :

        Dim a as IEnumerable(Of Integer) = GetA()
        
        MethodThatTakesIEnumerableOfObject(a.Cast(Of Object))
        

        【讨论】:

          猜你喜欢
          • 2012-01-25
          • 2017-07-20
          • 1970-01-01
          • 2012-03-30
          • 1970-01-01
          • 2019-10-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多