如果在Linq查询中引发异常,则分配列值

时间:2014-09-11 14:19:52

标签: c# arrays linq

我有一个查询,其中一个属性是路径" / Primary / secondary / tertiary /.../.../" 我的任务是通过斜杠拆分此路径,因此可以将每个子路径指定为查询结果中的属性。 问题是,长度会有所不同。有些路径的后分割数组长度为1,有些路径为7.因此我需要有7个不同的类别列:

var result = MySource.Where(ms => ...)
                     .Select(ms => new {
                        ID = ms.ID,
                        Name = ms.Name,
                        Category1 = ms.Path.Split('/')[0],
                        Category2 = ms.Path.Split('/')[1] //exception
                        ....                              //exception
                        Category7 = ms.Path.Split('/')[6] //exception
                     });

路径分割后,生成的数组具有不同的长度(1 - 7),导致ArgumentOutOfRangeException。我该如何规避这些例外?

我尝试过使用nullcoalescence运算符ms.Path.Split('/')[1] ?? "N/A",但没有帮助,因为没有结果但抛出异常。因此,每个速记if语句也会失败。

有没有办法捕获异常(在try catch块中换行?)所以如果数组超出界限,我可以指定一个默认值吗?

2 个答案:

答案 0 :(得分:3)

你的建模似乎有点破碎。填充单个集合而不是扁平的属性集。像这样:

Select(ms => new {
    ID = ms.ID,
    Name = ms.Name,
    Categories = ms.Path.Split('/')
})

更进一步,您可以创建一个实际(非匿名)模型来保存此信息,封装类别范围检查的逻辑。类似的东西:

Select(ms => new SomeObject(
    ms.ID,
    ms.Name,
    ms.Path.Split('/')
))

然后在SomeObject中你可以拥有各种逻辑,例如:

在构造函数中,您可以对值执行输入检查,包括提供的类别计数,以确保对象有效。

如果确实需要,可以将类别集合保密,并公开1-7的属性,这在内部执行此检查。 (虽然我真的不建议这样做。它为已经由集合处理的东西创建了一个不必要的变化点,索引值。)类似于:

public string Category1
{
    get
    {
        if (categories.Length < 1)
            return string.Empty;
        return categories[0];
    }
}

可能抛出异常而不是返回空字符串?也许做点什么?关键是将此逻辑封装在对象中,而不是在LINQ查询中或消耗代码中。

答案 1 :(得分:1)

你可以做到

Category7 = ms.Path.Split('/').ElementAtOrDefault(6) ?? "N/A",

请参阅演示:https://dotnetfiddle.net/4nTBhq

ElementAtOrDefault返回索引处的元素(例如6,如[6])但是如果超出范围则返回null。

优化,无需多次调用Split:

   .Select(ms => {
      var categories = ms.Path.Split('/');
      return new {
          ID = ms.ID,
          Name = ms.Name,
          ...
          Category7 = categories.ElementAtOrDefault(6),
      };
    })