C# 在LINQ中,orderby()是只执行一次比较函数,还是在需要时执行它?

C# 在LINQ中,orderby()是只执行一次比较函数,还是在需要时执行它?,c#,.net,linq,C#,.net,Linq,我找到了一种在互联网上洗牌数组的方法 Random rand = new Random(); shuffledArray = myArray.OrderBy(x => rand.Next()).ToArray(); 然而,我有点担心这个方法的正确性。如果OrderBy对同一个项目多次执行x=>rand.Next(),结果可能会冲突并导致奇怪的事情(可能是异常) 我试过了,一切都很好,但我仍然想知道这是否绝对安全,是否总是像预期的那样工作,我无法通过谷歌找到答案 谁能给我解释一下吗 提前感

我找到了一种在互联网上洗牌数组的方法

Random rand = new Random();
shuffledArray = myArray.OrderBy(x => rand.Next()).ToArray();
然而,我有点担心这个方法的正确性。如果OrderBy对同一个项目多次执行
x=>rand.Next()
,结果可能会冲突并导致奇怪的事情(可能是异常)

我试过了,一切都很好,但我仍然想知道这是否绝对安全,是否总是像预期的那样工作,我无法通过谷歌找到答案

谁能给我解释一下吗

提前感谢。

使用a肯定有效

至于orderby方法,我认为它不是完全随机的,因为保持了相等元素的顺序。因此,如果你有一个随机数组[5 6 7 2 6],那么两个6的元素的顺序总是相同的


我必须进行频率测试才能确定。你的方法应该有效,但速度很慢

它之所以有效是因为,
OrderBy
首先使用键选择器计算每个项目的键,然后对键进行排序。因此,每个项只调用一次键选择器

在.NET Reflector中,请参见类
EnumerableSorter
中的方法
ComputeKeys

this.keys = new TKey[count];
for (int i = 0; i < count; i++)
{
    this.keys[i] = this.keySelector(elements[i]);
}
// etc...
this.keys=new TKey[count];
for(int i=0;i
这是否绝对安全且始终按预期工作

它是无文件记录的,因此理论上它可能在未来发生变化

对于随机洗牌,您可以使用。这也是更有效的-只使用O(n)时间和就地洗牌,而不是O(n log(n))时间和O(n)额外内存

相关问题


我假设您讨论的是LINQ to对象,在这种情况下,用于比较的键对于每个元素只生成一次。(请注意,这只是当前实现的一个细节,可能会发生更改,但不太可能,因为这样的更改会引入您提到的bug。)

回答你更一般的问题:你的方法应该有效,但有更好的方法。使用
OrderBy
通常是O(n log n)性能,而a是O(n)


(如果您愿意,这里有一个或一个。)

问得好,我很好奇您会得到什么答案。非常感谢。事实上,我在C++中遇到过这样的错误。谢谢你的详细回答和建议。我不知道还有类似的问题。谢谢你的评论。如果我需要认真对待,我会考虑其他方法。嗯,至少它只需要几行。虽然排序规则执行稳定的排序,但键是按索引生成的,而不是按值生成的。因此,在生成随机键时,相同的值可能会被洗牌。