gpt4 book ai didi

c# - 序列不包含任何元素

转载 作者:太空狗 更新时间:2023-10-29 22:30:38 25 4
gpt4 key购买 nike

谁能解释一下为什么以下 LINQ 查询会抛出 InvalidOperationException?
(不要说列表没有元素,我要找的值一直存在于集合中)

class Program
{
static int lastNumber;
static void Main()
{
int loopCount = 100; int minValue = 1; int maxValue = 10000;
var numbers = Enumerable.Range(minValue, maxValue).ToList();//or ToArray();
Random random = new Random();

for (int i = 0; i < loopCount; i++)
{
//.First() throws the exception but it is obvious that the value exists in the list
int x = numbers.Where(v => v == NewMethod(minValue, maxValue, random)).First();
}
Console.WriteLine("Finished");
Console.ReadLine();

}

private static int NewMethod(int minValue, int maxValue, Random random)
{
var a1 = random.Next(minValue + 1, maxValue - 1);
lastNumber = a1;
return a1;
}
}

只有当我在 lambda 表达式中调用 NewMethod 时才会出现问题。
如果这样做它有效

int temp=NewMethod(minValue, maxValue, random);
int x = numbers.Where(v => v == temp).First();

我添加了lastNumber字段来帮助调试代码,崩溃时可以看到该值存在于集合中

附言
问题不在于随机变量,我删除了参数并在方法内部创建了一个新的局部随机数,但问题仍然存在

更新

事实证明,您不需要循环来使其崩溃。如果多次运行该程序,您将再次遇到错误

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
class Program
{
static int lastNumber;
static void Main()
{
int minValue = 1, maxValue = 100000;
var numbers = Enumerable.Range(minValue, maxValue).ToArray();
//Crashes sometimes
int x = numbers.Where(v => v == NewMethod(minValue, maxValue)).First();
Console.WriteLine("Finished");
Console.ReadLine();
}

private static int NewMethod(int minValue, int maxValue)
{
Random random = new Random();
var a1 = random.Next(minValue + 1, maxValue - 1);
lastNumber = a1;
return a1;
}
}

最佳答案

@Oleg 是对的,但这就是问题所在。原因

Where 扫描列表以查找符合给定条件的元素。在这种情况下,每个元素的条件都会发生变化。如果你把问题变小了,比如说一个包含 5 个元素的数组:

List<Int32> (5 items)
1
2
3
4
5

然后循环寻找匹配某个随机数的值(x 是 Item[i]r 是一个随机数):

Item 1: x = 1, r = 2  // fail
Item 2: x = 2, r = 3 // fail
Item 3: x = 3, r = 2 // fail
Item 4: x = 4, r = 3 // fail
Item 5: x = 5, r = 2 // fail

请注意,没有任何项目与该特定随机数匹配,因此没有项目与条件匹配,First 将引发异常!

如您所见,解决方法是在枚举之前生成随机数:

int temp=NewMethod(minValue, maxValue, random);  // say 2

Item 1: x = 1, temp = 2 // fail
Item 2: x = 2, temp = 2 // success!

边注:

这里使用 maxValue 有点误导:

 Enumerable.Range(minValue, maxValue)

因为 Enumerable.Range 的第二个参数是结果集合的长度,而不是最大值。在这种情况下,它可以工作,因为您从 1 开始,但如果您使用 99 和 100,结果会出乎意料 - 您会得到 99 到 198 的范围。

关于c# - 序列不包含任何元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30926492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com