我有一个查询,其中一个属性是路径" / 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块中换行?)所以如果数组超出界限,我可以指定一个默认值吗?
答案 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),
};
})