为什么我不能将 List分配给到 IEnumerable;在.NET 4.0中

发布于 2024-12-17 05:51:45 字数 410 浏览 4 评论 0原文

我尝试这样做:

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”。存在显式转换(您是否缺少强制转换?)

这是为什么?

I try to do this:

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

it works great!

But when I try to do this:

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

Visual Studio tells me:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?)

Why is that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我爱人 2024-12-24 05:51:45

简而言之:.NET 4 中的通用方差不支持作为值类型的类型参数的方差。

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

对于值类型来说,情况并非如此,对于转换不是“引用转换”(即保留表示形式的转换)的引用类型来说,情况并非如此。这就是为什么你不能写 IEnumerable;顺便说一下,names = new List();...

Simply put: generic variance in .NET 4 doesn't support variance for type arguments which are value types.

The reason it can work for reference types is that once the CLR has decided it knows the generic conversion is safe, it can treat all reference values the same way - they have the same representation internally. No actual conversion is required to turn a string reference into an object reference, or vice versa if you know it's definitely a reference to a string - it's the same bits, basically. So the generated native code can just treat the references as references, happy in the knowledge that the rules around variance have guaranteed that nothing nasty will happen at the type safety level, and not performing any conversions on the values themselves.

That isn't true for value types, or for reference types where the conversion isn't a "reference conversion" (i.e. a representation-preserving one). That's why you can't write IEnumerable<XName> names = new List<string>(); by the way...

作妖 2024-12-24 05:51:45

来自 MSDN 博客 > C# 常见问题 >协方差和逆变常见问题解答

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

// int 是值类型,因此代码无法编译。
IEnumerable<对象>对象 = new List(); // 这里编译器错误。

From MSDN Blogs > C# Frequently Asked Questions > Covariance and Contravariance FAQ:

Variance is supported only if a type parameter is a reference type. Variance is not supported for value types.
The following doesn’t compile either:

// int is a value type, so the code doesn't compile.
IEnumerable<Object> objects = new List<int>(); // Compiler error here.
潇烟暮雨 2024-12-24 05:51:45

另一个解决方案是使用扩展方法 Enumerable.Cast ,如下所示:

Dim a as IEnumerable(Of Integer) = GetA()

MethodThatTakesIEnumerableOfObject(a.Cast(Of Object))

Another solution would be to use the extension method Enumerable.Cast as such:

Dim a as IEnumerable(Of Integer) = GetA()

MethodThatTakesIEnumerableOfObject(a.Cast(Of Object))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文