简体   繁体   English

何时使用LINQ的.ToList()或.ToArray()

[英]When to use LINQ's .ToList() or .ToArray()

After running this code: 运行此代码后:

var input = new List<T>( ... );
var result = input.Select( t => new U(t) );

U first1 = null;
foreach ( U u1 in result )
    if ( first1 == null )
        first1 = u1;

U first2 = null;
foreach ( U u2 in result )
    if ( first2 == null )
        first2 = u2;

Then 'first1 == first2' evaluates to false even though both U's wrap the same T. I haven't tested it yet, but I think it can be made to evaluate to true by chaining a .ToList() or .ToArray() onto the Select() call. 然后'first1 == first2'评估为false,即使两个U都包含相同的T.我还没有测试它,但我认为可以通过链接.ToList()或.ToArray()来评估为true进入Select()调用。

In real code, which is much more complex than this simple illustration, what is a good rule of thumb to use for deciding if .ToList() or .ToArray() should be appended? 在比这个简单的插图复杂得多的实际代码中,用于决定是否应该附加.ToList()或.ToArray()的好经验法则是什么? My initial thoughts are either any referenced expression that may be iterated more than once or, to be safer in case potential iterations are not obvious, any referenced expression whose result will never change. 我最初的想法是要么可以多次迭代的任何引用表达式,要么在潜在迭代不明显的情况下更安全,任何引用的表达式,其结果永远不会改变。

Unfortunately, I don't think there is a good "hard and fast" rule here. 不幸的是,我不认为这里有一个很好的“硬性和快速”规则。 It depends a lot on how you expect the results to be used, and what the query itself is actually doing. 这很大程度上取决于您对结果的使用方式以及查询本身实际执行的操作。

My initial thoughts are either any expression that may be iterated more than once or, to be safer in case potential iterations are not obvious, any expression whose result will never change. 我最初的想法是要么可以多次迭代的任何表达式,要么在潜在的迭代不明显的情况下更安全,任何结果永远不会改变的表达式。

In general, if you're going to use the result of a query more than once, it's always a good idea to store it via ToList() or ToArray() . 通常,如果您要多次使用查询结果,通过ToList()ToArray()存储它总是一个好主意。 This is especially true if you're LINQ query is an "expensive" one, as it prevents the expensive operation from running more than once. 如果您的LINQ查询是“昂贵的”,则尤其如此,因为它可以防止昂贵的操作多次运行。

Typically, if you're only going to enumerate the results, then I would leave it as IEnumerable<T> . 通常情况下,如果您只是枚举结果,那么我会将其保留为IEnumerable<T> If you plan to store the results, or use the results more than once, then storing it in a collection can be beneficial. 如果您计划存储结果,或多次使用结果,那么将其存储在集合中可能是有益的。

The other place to watch for is if you return the results in a public API. 另一个需要注意的地方是,如果您在公共API中返回结果。 While it's often nice to return IEnumerable<T> , depending on the expected use case, you may want to consider using ToList() to prevent the operation from being executed more than once. 虽然返回IEnumerable<T>通常很好,但根据预期的用例,您可能需要考虑使用ToList()来防止操作被多次执行。

As for whether to use ToList() or ToArray() , it really depends on how you'll use the results. 至于是否使用ToList()ToArray() ,它实际上取决于你将如何使用结果。 The cost associated with each is nearly identical ( ToList() actually has slightly lower execution overhead if the input is not ICollection<T> ). 与每个相关的成本几乎相同(如果输入不是ICollection<T>ToList()实际上具有略低的执行开销。 Typically, I prefer ToList() over ToArray() unless I have a specific need or desire for an array. 通常,我更喜欢ToList()不是ToArray()除非我对数组有特定需求或期望。

ToList calls List<T>(IEnumerable<T>) constructor to create a List<T> , while ToArrary uses an internal class Buffer<T> to grow the array. ToList调用List<T>(IEnumerable<T>)构造函数来创建List<T> ,而ToArrary使用内部类Buffer<T>来增长数组。

If the source collection ( IEnumerable<T> ) implements the ICollection interface, the two methods use similar code logic to copy the data. 如果源集合( IEnumerable<T> )实现ICollection接口,则这两种方法使用类似的代码逻辑来复制数据。

ICollection.CopyTo(array, 0);  

Otherwise, ToList will creates the List<T> dynamically. 否则, ToList将动态创建List<T> While ToArray copies the element one by one into a new array. ToArray将元素逐个复制到新数组中。 If the array is full, the method doubles the array size to hold the data. 如果数组已满,则该方法将数组大小加倍以保存数据。 Finally the method returns another array based on the source collection's size. 最后,该方法根据源集合的大小返回另一个数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM