IEumable IndexOutOfRangeException异常 [英] IEnumerable IndexOutOfRangeException

查看:24
本文介绍了IEumable IndexOutOfRangeException异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么使用此代码会得到System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

IEnumerable<char> query = "Text result";
string illegals = "abcet";

for (int i = 0; i < illegals.Length; i++)
{
    query = query.Where(c => c != illegals[i]);
}

foreach (var item in query)
{
    Console.Write(item);
}

请解释一下我的代码出了什么问题。

推荐答案

问题是,您的lambda表达式捕获变量i,但直到循环之后才执行委托。执行表达式c != illegals[i]时,iillegals.Length,因为这是i的最终值。重要的是要理解lambda表达式捕获变量,而不是"lambda表达式转换为委托时那些变量的值"。

以下是修复代码的五种方法:

选项1:I的本地副本

i的值复制到循环内的局部变量中,这样循环的每次迭代都会捕获lambda表达式中的一个新变量。循环的其余执行过程不会更改该新变量。

for (int i = 0; i < illegals.Length; i++)
{
    int copy = i;
    query = query.Where(c => c != illegals[copy]);
}

选项2:在lambda表达式之外提取非法移民[i]

在循环中提取illegals[i]的值(在lambda表达式之外),并在lambda表达式中使用该值。同样,更改i的值不会影响变量。

for (int i = 0; i < illegals.Length; i++)
{
    char illegal = illegals[i];
    query = query.Where(c => c != illegal);
}

选项3:使用Foreach循环

此选项仅适用于C#5和更高版本的编译器,因为foreach在C#5中的含义已更改(变得更好)。

foreach (char illegal in illegals)
{
    query = query.Where(c => c != illegal);
}

选项4:使用一次Except

LINQ提供执行集合排除的方法:Except。这与前面的选项不太一样,因为您只会得到输出中任何特定字符的单个副本。因此,如果e不在illegals中,您将使用上述选项得到"tex resul",但使用Except得到"tex rsul"。不过,还是值得了解的:

// Replace the loop entirely with this
query = query.Except(illegals);

选项5:使用一次Contains

您可以调用Where一次,调用Contains的lambda表达式:

// Replace the loop entirely with this
query = query.Where(c => !illegals.Contains(c));

这篇关于IEumable IndexOutOfRangeException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆