C#中lambda变量的范围是什么?

mfc*_*mfc 65 c# lambda scope

我对lambda变量的范围感到困惑,例如以下内容

var query = 
    from customer in clist
    from order in olist
    .Where(o => o.CustomerID == customer.CustomerID && o.OrderDate ==  // line 1
        olist.Where(o1 => o1.CustomerID == customer.CustomerID)        // line 2
             .Max(o1 => o1.OrderDate)                                  // line 3
    )
    select new {
        customer.CustomerID,
        customer.Name,
        customer.Address,
        order.Product,
        order.OrderDate
    };
Run Code Online (Sandbox Code Playgroud)

在第1行中,我声明了一个lambda变量'o',这意味着我不能在第2行再次声明它(或者至少编译器在我尝试时会抱怨)但是即使'o1'已经存在,它也不会抱怨第3行??

lambda变量的范围是什么?

yam*_*men 174

括号给出了线索​​ - lambda变量在声明它的范围内捕获:

.Where(o => ... olist.Where(o1 => ...).Max(o1 => ...))
  //  |----------------------------------------------| scope of o
  //                       |---------|                 scope of first o1
  //                                      |---------|  scope of second o1
Run Code Online (Sandbox Code Playgroud)

请注意,两个o1变量没有重叠,但它们都重叠(或隐藏)o变量,因此不能使用相同的名称.

  • @ kizzx2你应该经常来这里:) (7认同)
  • 我在3年后见过的最佳答案. (3认同)

Bol*_*ock 14

lambda参数的范围等于lambda表达式主体的整个范围,包括任何内部lambda表达式或范围.

如果我们扩展lambda表达式的语法并添加一些友好的缩进,它可能会变得更清晰(尽管可能没有yamen的图解答案那么明确!):

.Where(o => {
    return o.CustomerID == customer.CustomerID
        && o.OrderDate == olist.Where(
            o1 => o1.CustomerID == customer.CustomerID
        )
        .Max(
            o1 => o1.OrderDate
        );
})
Run Code Online (Sandbox Code Playgroud)

请注意,您的.Where().Max()呼叫位于外部.Where().的o在外部的λ是由您内lambda表达式内的外的λ封装(这被称为闭合),从而使得它在你的内lambda表达式的范围中已经存在,并且不能被重新使用作为参数.

您可以重复使用,o1因为您的两个内部lambda彼此完全分离,因此它不会超出任何一个范围.


Fré*_*idi 5

如果其中一个范围包含另一个范围,则不能在两个范围中使用相同的变量名称.

在您的问题中,o是在外部范围中引入的,因此它不能在第二个Where()或中使用Max(),因为这些范围包含在外部范围内.

另一方面,您可以o1在两个内部范围中使用,因为一个不包含另一个范围,因此没有歧义.