我有这样一个简单的LinQ查询:
myList.Where(x=> x.Property.Property2 == 5);
但是,Property可能为null,然后我收到错误。所以我想知道是否有办法检查它是否为null,如果不为null,进行比较,如果为null,则抛出异常。
因为如果没有,我必须使用foreach来检查每个元素,这样:
List<MyType> myLstResult = new List<MyType>();
foreach(MyType iterator in myList)
{
if(iterator.Property == null)
{
throw new ArgumentNullException();
}
if(iterator.Property.Property2 == 5)
{
myLstresult.Add(iterator);
}
}
感谢。
答案 0 :(得分:7)
是的,您可以像这样扩展lambda:
myList.Where(x=>
{
if (x.Property == null)
throw new ArgumentNullException();
return x.Property.Property2 == 5;
});
这当然只适用于“普通”linq。 Linq-to-sql或-entity查询提供程序可能无法将其转换为sql。
答案 1 :(得分:7)
我会避免异常。
您可以使用新的C#6空传播运算符:
myList.Where(x=> x.Property?.Property2 == 5);
或这个简单的方法:
myList.Where(x=> x.Property != null && x.Property.Property2 == 5);
但是,如果你真的想抛出一个异常,我会使用一个更容易调试的普通循环。建议这样做,因为LINQ查询不应导致副作用或抛出异常:
https://msdn.microsoft.com/en-us/library/bb513730.aspx
但是,我们建议您避免在查询中调用任何方法 表达式,可以创建副作用,如修改 数据源的内容或抛出异常
因此,您已经展示的foreach
循环(我最喜欢的)或try-catch
:
List<MyType> myLstResult = null;
try
{
myLstResult = myList.Where(x=> x.Property.Property2 == 5).ToList();
}
catch(NullReferenceException nullref)
{
throw new ArgumentNullException("MyType.Property must not be null", nullref);
}
// ...
Rene has shown另一种我不建议抛出异常的方法。这不能从Linq-To-Sql
或Linq-To-Entities
等LINQ提供程序转换,并违反上述指南。
更新:也许像这样的ThrowIfArgumentNull
扩展方法会派上用场:
public static IEnumerable<TSource> ThrowIfArgumentNull<TSource, TNullable>(this IEnumerable<TSource> enumeration, Func<TSource, TNullable> mightBeNullSelector, string argumentName)
where TNullable : class
{
foreach (TSource item in enumeration)
{
if (mightBeNullSelector(item) == null)
throw new ArgumentNullException(argumentName);
yield return item;
}
}
你会以这种方式使用它:
List<MyType> myLstresult = myList
.ThrowIfArgumentNull(x => x.Property, "MyType.Property")
.Where(x => x.Property.Property2 == 5)
.ToList();