C# 是否可以在LinQ中使用条件inside where子句?

C# 是否可以在LinQ中使用条件inside where子句?,c#,.net,linq,C#,.net,Linq,我有一个简单的LinQ查询: myList.Where(x=> x.Property.Property2 == 5); List<MyType> myLstResult = new List<MyType>(); foreach(MyType iterator in myList) { if(iterator.Property == null) { throw new ArgumentNullException(); }

我有一个简单的LinQ查询:

myList.Where(x=> x.Property.Property2 == 5);
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);
    }
}
List<MyType> myLstresult = myList
    .ThrowIfArgumentNull(x => x.Property, "MyType.Property")
    .Where(x => x.Property.Property2 == 5)
    .ToList();
但是,属性可以为null,然后我会得到一个错误。因此,我想知道是否有任何方法可以检查它是否为null,如果不是null,则进行比较,如果为null,则抛出异常

因为如果不是,我必须使用foreach检查每个元素,方法如下:

myList.Where(x=> x.Property.Property2 == 5);
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);
    }
}
List<MyType> myLstresult = myList
    .ThrowIfArgumentNull(x => x.Property, "MyType.Property")
    .Where(x => x.Property.Property2 == 5)
    .ToList();
List myLstResult=new List();
foreach(myList中的MyType迭代器)
{
if(iterator.Property==null)
{
抛出新ArgumentNullException();
}
if(iterator.Property.Property2==5)
{
myLstresult.Add(迭代器);
}
}

谢谢。

是的,您可以像这样扩展lambda:

myList.Where(x=> 
    {
        if (x.Property == null)
            throw new ArgumentNullException();
        return x.Property.Property2 == 5;
    });


这当然只能在“正常”linq中工作。Linq到sql或-实体查询提供程序可能无法将其转换为sql。

我将避免出现异常

您可以使用新的C#6 null传播运算符:

myList.Where(x=> x.Property?.Property2 == 5);
或者这种简单的方法:

 myList.Where(x=> x.Property != null && x.Property.Property2 == 5);
然而,如果你真的想抛出一个异常,我会使用一个简单的循环,这也更容易调试。建议这样做,因为LINQ查询不应导致副作用或引发异常:

但是,我们建议您避免在查询中调用任何方法 可产生副作用的表达式,例如修改 数据源的内容或引发异常

因此,您已经显示的
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);
}
// ...
您可以这样使用它:

myList.Where(x=> x.Property.Property2 == 5);
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);
    }
}
List<MyType> myLstresult = myList
    .ThrowIfArgumentNull(x => x.Property, "MyType.Property")
    .Where(x => x.Property.Property2 == 5)
    .ToList();
List myLstresult=myList
.ThrowIfArgumentNull(x=>x.Property,“MyType.Property”)
.其中(x=>x.Property.Property2==5)
.ToList();

我不喜欢导致异常的查询。那我当然更喜欢环道。“但是,我们建议您避免在查询表达式中调用任何可能产生副作用的方法,例如修改数据源的内容或引发异常”@TimSchmelter我同意,但这正是OP所要求的。@TimSchmelter Waht是myList.Where(x=>x.Property?.Property2==5)的问题所在?@RoyiNamir,OP想抛出一个
ArgumentNullException
,而不是回避它。@TimSchmelter Oh Ok。您可以首先将数据划分为有效/无效,并在循环之后检查空值。取决于数据量,以及在发现空值时是否需要异常。