C# ToArray()与new JArray():转换IEnumerable哪一种更有效<;T>;收集<;T>;

C# ToArray()与new JArray():转换IEnumerable哪一种更有效<;T>;收集<;T>;,c#,linq,json.net,C#,Linq,Json.net,我需要将LINQ查询的IEnumerable结果转换为一个集合,以便对其使用索引。现在我发现基本上有两种方法 我可以使用ToArray()将其转换为JToken[]: JToken[] arrElementValues = arrResults.Where(joResults => joResults["uResultId"]?.ToString() == arrTaskResults[intResult]["uResultId"]?.ToString() &&

我需要将
LINQ
查询的
IEnumerable
结果转换为一个集合,以便对其使用索引。现在我发现基本上有两种方法

我可以使用
ToArray()
将其转换为
JToken[]

JToken[] arrElementValues = arrResults.Where(joResults => joResults["uResultId"]?.ToString() == arrTaskResults[intResult]["uResultId"]?.ToString() &&
                                       joResults["iElementId"]?.ToString() == strUniqueElementId && joResults["iContainerId"]?.ToString() == strContainerId).ToArray();
或者我可以将
IEnumerable
传递给
JArray()

IEnumerable enmElementValues=arrResults.Where(joResults=>joResults[“uResultId”]?.ToString()==arrTaskResults[intResult][“uResultId”]?.ToString()&&
joResults[“iElementId”]?.ToString()=struniquelementId&&joResults[“iContainerId”]?.ToString()=strContainerId);
JArray arrElementValues=新的JArray(enmElementValues);

那么,哪一种方法更好、更有效呢?

选择数组,因为它在内存中是固定大小的结构。

您还可以对列表进行索引(
IReadOnlyList
)。在您的情况下,输入序列的长度未知,因此
ToArray
将使用与
ToList
中使用的代码类似的代码,随着项目数量的增加,增加存储枚举项目的缓冲区。最初,列表的容量为4项。枚举第5项时,将创建一个大小为两倍的新缓冲区,并将原始缓冲区复制到新缓冲区(您不能在.NET中扩展已分配的数组)。此过程将继续,直到所有项目都已枚举

如果序列有10个项目,那么最终缓冲区将有16个项目的容量(4*2*2)。使用
ToList
将返回使用此缓冲区的列表,但使用
ToArray
将创建一个包含10个项目的新数组,并将缓冲区复制到数组中,从而缩小最终存储空间,从而不存在多余容量

因此,如果项目数量与容量4、8、16、32……中的一个不匹配,则使用
ToList
比使用
ToArray
使用更少的CPU。。。(跳过最终分配),但可以使用更多内存(缓冲区中未使用的容量)

使用
JArray
添加了注释中提到的附加语义,虽然它的性能可能与
ToList
ToArray
一样好,但它似乎不太可能包含某种超快速算法,用于枚举序列并将项存储在内存缓冲区中,这比
ToList
可以


对于使用
ToList
ToArray
的小序列,不应产生任何可感知的差异,如果您确实存在性能问题,则应在决定如何解决之前对其进行测量。

从逻辑上讲,JArray是JSON结构中数组的表示

JToken[]
在逻辑上是一个JSON令牌数组


就我个人而言,我更喜欢调用
ToArray
并拥有一个jtoken数组,因为我并没有在这里构建一个JSON数组——我只是在内存中收集一堆jtoken来处理它们。如果我想构造或解构一个实际的JSON结构,我只会使用
JArray
。它不是JToken[]

的替代品,您为什么不自己编写一个微基准测试并查看呢?您是否分析了代码以了解是否存在性能问题?这不太可能是个大问题。此外,含义是不同的:一个是令牌数组,另一个是JSON数组的表示。使用最适合您的用例的@Rob这不是性能问题,到目前为止,这两种方法都可以正常工作。我只是想知道哪种方法更好,这样我就可以在整个项目中使用相同的方法。@izengod好吧,除非您需要
JArray
,否则我认为使用常规的.NET内置数组更有意义。当您将预先存在的
JToken
添加到
JArray
中时,如果
JToken
已经有一个标记,那么添加的标记将实际被克隆。如果需要,请使用
JArray
。如果您不希望这样,请使用数组。如果您不在乎,那么选择任何一个.OP,明确表示需要数组,以便它们可以索引元素,而不是
IEnumerable
.OP,请转到数组then@VijayRaheja这就是问题所在,对于数组,哪种转换更好,因为它在内存中是固定大小的结构。@VijayRaheja:如果这是您的答案,那么您应该编辑您的答案以反映这一点。从目前的情况看,你的答案似乎并没有反映出你现在在评论中所说的话。答对了!我一直在寻找的答案。感谢您的时间和解释:)
IEnumerable<JToken> enmElementValues = arrResults.Where(joResults => joResults["uResultId"]?.ToString() == arrTaskResults[intResult]["uResultId"]?.ToString() &&
                                       joResults["iElementId"]?.ToString() == strUniqueElementId && joResults["iContainerId"]?.ToString() == strContainerId);

JArray arrElementValues = new JArray(enmElementValues);