如何防止LINQ WHERE中的System.IndexOutOfRangeException?

时间:2016-01-22 14:24:43

标签: c# linq split

我在String.Split使用随机字符串时遇到此异常。

List<string> linhas = new List<string>();

linhas.Add("123;abc");
linhas.Add("456;def");
linhas.Add("789;ghi");
linhas.Add("chocolate");

var novas = linhas.Where(l => l.ToString().Split(';')[1]=="def");

2 个答案:

答案 0 :(得分:12)

最后一个字符串"chocolate"不包含";",因此String.Split会返回一个包含单个字符串"chocolate"的数组。这就是为什么如果你试图访问第二个,你会得到异常的原因。

您可以使用ElementAtOrDefault代替字符串返回null

var novas = linhas.Where(l => l.Split(';').ElementAtOrDefault(1) == "def");

使用匿名类型的更长方法:

var novas = linhas
    .Select(l => new { Line = l, Split = l.Split(';') })
    .Where(x => x.Split.Length >= 2 && x.Split[1] == "def")
    .Select(x => x.Line);

答案 1 :(得分:1)

我将对Tim的回答进行一些扩展,并展示在LINQ查询中做一些额外事情的方法。

您可以扩展Where子句中的逻辑来执行一些额外的过程,这可以使您的代码更具可读性。这对于小事来说会很好:

var novas = linhas.Where(l => 
            {
                var parts = l.Split(':');

                return parts.Length > 1 ? parts[1] == "def" : false;
            });

如果您需要多个语句,可以将子句的主体包装在花括号中,但是需要return关键字。

或者,如果您有大量信息会使内联内容变得难以理解,那么您也可以在查询中使用单独的方法。

public void FindTheStringImLookingFor()
{
    var linhas = new List<string>();

    linhas.Add("123;abc");
    linhas.Add("456;def");
    linhas.Add("789;ghi");
    linhas.Add("chocolate");

    var words = linhas.Where(GetTheStringIWant);
}

private bool GetTheStringIWant(string s)
{
    var parts = s.Split(':');

    // Do a lot of other operations that take a few lines.

    return parts.Length > 1 ? parts[1] == "def" : false;
}