【问题标题】:Does Array.ToArray<>() return the original array if it is the same type?如果 Array.ToArray<>() 是相同类型,它是否返回原始数组?
【发布时间】:2010-01-19 10:39:45
【问题描述】:

我每天都在处理一个框架,我们有时会提供接受 IEnumerable&lt;MyBusinessObject&gt; 作为参数的方法,以便显示用户界面、执行计算等。

如果我像这样传入MyBusinessObject 的数组:

MyBusinessObject[] myArray = new MyBusinessObject { obj1, obj2, ..., objN };
frameworkClass.MyMethod(myArray);

....

public class FrameworkClass
{
    public void MyMethod(IEnumerable<MyBusinessObject> objs)
    {
        // Other code that uses the enumerable
        MyBusinessObject[] objectArray = objs.ToArray();            
        // More code that uses the enumerable
    }
}

objs.ToArray() 行是简单地将IEnumerable&lt;MyBusinessObject&gt; 解析回原始数组,还是将其复制到一个全新的数组以供使用?

【问题讨论】:

    标签: c# linq extension-methods


    【解决方案1】:

    不,您将总是获得数组的新副本,虽然其中的对象不是副本,但它们与原始数组中的引用相同。

    如果对返回数组的更改有时会影响源,有时不会影响源,这将是非常不一致的。 ToList 出于同样的原因以同样的方式工作。


    如果您需要查看详细信息,您可以检查源代码(截至 2015 年):Enumerable.ToArray 反过来创建元素的副本(针对 ICollection 和因此 Array[] 优化,但仍在制作副本)和内部 @ 987654322@。

    【讨论】:

    • 我不确定这是否应该是另一个问题,但我只是想快速看看你是否也知道这一点:IEnumerable&lt;T&gt;.Count() 是否调用数组的.Length 属性来获得结果,或者它会做一些非常低效的事情吗?
    • 必须为那个向斯基特先生鞠躬。就个人而言,我敢打赌它没有(IEnumerable 没有 Length 属性)。然而,作为优化,它有可能为某些场景做一些聪明的反射。要点是,如果您想要计数,则 IEnumerable 不合适 - IList 是。
    • @Codesleuth:查看the source codeCount 方法检查对象是否实现了ICollection&lt;T&gt;ICollection(数组实现)并使用其Count 属性而不是循环通过项目。
    【解决方案2】:

    如果其中有一个或多个元素,您将获得数组的新副本。对于空数组,您可能会得到相同的数组,至少在 .NET 5 中:

    Console.WriteLine(Object.ReferenceEquals(Array.Empty<string>(), Array.Empty<string>().ToArray()));
    

    这返回真。

    【讨论】:

    • 很酷的发现。由于您不能附加到数组,因此这不太可能真正重要。但仍然很有趣!
    猜你喜欢
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2015-03-13
    • 1970-01-01
    相关资源
    最近更新 更多