c# - 从 IEnumerable 转换为 IEnumerable<object>

标签 c# arrays linq ienumerable language-lawyer

我更喜欢使用 IEnumerable<object> ,因为 LINQ 扩展方法在其上定义,而不是 IEnumerable ,这样我就可以使用,例如,range.Skip(2) .但是,我也更喜欢使用 IEnumerable , 对于 T[]可隐式转换为 IEnumerable是否T是引用类型还是值类型。对于后一种情况,不涉及拳击,这很好。结果,我可以做到 IEnumerable range = new[] { 1, 2, 3 } .将两个世界的优点结合起来似乎是不可能的。反正我选择安家IEnumerable并在我需要应用 LINQ 方法时进行某种转换。

来自 this SO线程,我开始知道range.Cast<object>()能够胜任这项工作。但它会产生性能开销,我认为这是不必要的。我尝试执行像 (IEnumerable<object>)range 这样的直接编译时转换.根据我的测试,它适用于引用元素类型但不适用于值类型。有什么想法吗?

仅供引用,问题源于 this GitHub 问题。而我使用的测试代码如下:

static void Main(string[] args)
{
    // IEnumerable range = new[] { 1, 2, 3 }; // won't work
    IEnumerable range = new[] { "a", "b", "c" };
    var range2 = (IEnumerable<object>)range;
    foreach (var item in range2)
    {
        Console.WriteLine(item);
    }
}

最佳答案

According to my tests, it works for reference element type but not for value type.

正确。这是因为 IEnumerable<out T> 是协变的,并且co-variance/contra-variance is not supported for value types .

I come to know that range.Cast() is able to do the job. But it incurs performance overhead which is unnecessary in my opinion.

IMO 如果你想要一个对象集合和给定的值类型集合,那么性能成本(由装箱带来)是不可避免的。使用非通用 IEnumerable不会避免拳击因为IEnumerable.GetEnumerator提供一个 IEnumerator谁的.Current属性返回 object .我宁愿总是使用 IEnumerable<T>而不是 IEnumerable .所以只需使用 .Cast方法而忘记拳击。

关于c# - 从 IEnumerable 转换为 IEnumerable<object>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38451939/

相关文章:

C# 无法设置对象

linq - LINQ 是否支持可组合的 "OR Queries"?

Javascript/Webix 将对象引用为数组

c# - 在 LINQ-to-Entities 中键入成员支持?

c# - 为什么 Linq 无法将表达式翻译/视为本地表达式并引发异常?

c# - 错误 : 22001: value too long for type character varying(255)

c# - 在单个 exe 中捆绑 .net exe、dll、.net 环境和 native dll

c# - ASP.NET 中的动态表单生成

java - 使用 for 循环组合 1 个数组的元素以创建一个新数组

c - C语言中如何计算数组的元素个数?