为什么不能在方法主体内访问将其作为LINQ函数的谓词传递给它的变量?

时间:2018-11-15 09:52:35

标签: c# lambda

我去尝试访问方法内部的lambda变量,但是我惊讶地发现我做不到。更具体地说,关于下面的代码,我访问了传递给item调用的IEnumerable.Any()变量作为谓词,以访问特定项目的属性。但是我无法这样做。

当然,如果我将该项作为参数传递给方法,则应该可以在方法主体中访问它。但这种情况并非如此。为什么是这样?如何更改代码以访问item的属性?

if (list.Any(item => item.questions == null))
            {
                throw new ArgumentException($"Item {item.Name} cannot be null"); //<-- Error here, "item" does not exist in current context.
            }

3 个答案:

答案 0 :(得分:1)

您不能那样做。 Lambda表达式基本上是具有自己范围的匿名方法。

相反,您可以做的是:

var nulls = list.Where(item => item.questions == null);

if (nulls.Any())
{
    throw new ArgumentException(String.Format("Item {0} cannot be null"), nulls.First().Name)); 
}

答案 1 :(得分:1)

Lambda表达式item => ...定义了范围, item 仅在lambda内部可用。如果您需要查找特定项目,请尝试以下操作:

var firstItemWithoutQuestions = list.FirstOrDefault(item => item.questions == null);
if (firstItemWithoutQuestions != null) 
{
   throw new ...
}

答案 2 :(得分:0)

如果我们看一下您的代码:

if (
    list.Any(item => item.questions == null) // <-- item is only in scope of Any!
)
{
    throw new ArgumentException($"Item {item.Name} cannot be null");
}

您在代码段的第2行中只能在Any内使用此项目,而不能在if-body内使用。

您可以对集合执行ForEach,但是异常只会抛出在第一个元素上

list.Foreach(item => 
{
    if(item.questions == null)
        throw new ArgumentException($"Item {item.Name} cannot be null");
}