我有这样一个简单的LinQ查询:
myList.Where(x=> x.Property.Property2 == 5);
Run Code Online (Sandbox Code Playgroud)
但是,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);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢.
是的你可以像这样扩展lambda:
myList.Where(x=>
{
if (x.Property == null)
throw new ArgumentNullException();
return x.Property.Property2 == 5;
});
Run Code Online (Sandbox Code Playgroud)
这当然只适用于"普通"linq.Linq-to-sql或-entity查询提供程序可能无法将其转换为sql.
我会避免例外.
您可以使用新的C#6空传播运算符:
myList.Where(x=> x.Property?.Property2 == 5);
Run Code Online (Sandbox Code Playgroud)
或者这个简单的方法:
myList.Where(x=> x.Property != null && x.Property.Property2 == 5);
Run Code Online (Sandbox Code Playgroud)
但是,如果你真的想抛出一个异常,我会使用一个更容易调试的普通循环.建议这样做,因为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);
}
// ...
Run Code Online (Sandbox Code Playgroud)
Rene已经展示了另一种我不建议抛出异常的方法.这不能从LINQ提供商那样翻译,Linq-To-Sql或者Linq-To-Entities违反上述指南.
更新:也许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;
}
}
Run Code Online (Sandbox Code Playgroud)
你会以这种方式使用它:
List<MyType> myLstresult = myList
.ThrowIfArgumentNull(x => x.Property, "MyType.Property")
.Where(x => x.Property.Property2 == 5)
.ToList();
Run Code Online (Sandbox Code Playgroud)