什么是C#中的λ变量的范围是什么?(What is the scope of a lambda va

2019-06-24 06:30发布

我感到困惑λ变量的范围,就拿下面

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
    };

在1号线我有声明λ变量的“o”,这意味着我不能在2号线再次声明(或至少编译器会抱怨,如果我尝试),但它并没有抱怨3号线,即使“01”已存在??

什么是λ变量的范围是什么?

Answer 1:

括号给的线索 - λ变量是在它的声明,其中的范围捕获:

.Where(o => ... olist.Where(o1 => ...).Max(o1 => ...))
  //  |----------------------------------------------| scope of o
  //                       |---------|                 scope of first o1
  //                                      |---------|  scope of second o1

请注意,有两个没有重叠o1变量,但他们都重叠(或阴影)的o变量,因此不能使用相同的名称。



Answer 2:

的λ参数的范围是等于lambda表达式的主体中,包括任何内lambda表达式或范围的整个范围。

如果我们扩大你的lambda表达式的语法,并添加一些友好的缺口可能会清晰一些(尽管可能无处为清晰衙门的图解答案 !):

.Where(o => {
    return o.CustomerID == customer.CustomerID
        && o.OrderDate == olist.Where(
            o1 => o1.CustomerID == customer.CustomerID
        )
        .Max(
            o1 => o1.OrderDate
        );
})

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

您可以重复使用o1因为你的两个内部lambda表达式是彼此完全独立的,所以它不会活过任何一个的范围。



Answer 3:

如果将作用域的一个包含其他不能在两个作用域使用相同的变量名。

在你的问题, o在外部范围推出,所以它不能在第二次再次使用Where()Max()因为这些范围都包含在外层一个。

在另一方面,你可以使用o1在两个内部范围,因为一个不包含其他的,所以没有歧义存在。



Answer 4:

becasue LAMDA是更换匿名函数在这里你的代码

相同的范围内

Where(o => o.CustomerID == customer.CustomerID && o.OrderDate ==   //line 1
         olist.Where(o1 => o1.CustomerID == customer.CustomerID)   //line 2     

是的功能范围,其中varialble“O”活

这里三线,这也就是新的功能范围变量的新scrop

不同的适用范围

  .Max(o1 => o1.OrderDate)   )        //line 3

使得在第1行所定义的第1行和第2行varialbe“○”的RESON不能LINE2定义的,因为相同的scrop和“01”定义LINE2 becauase它是在不同的功能范围,可以在再次line3中的定义



Answer 5:

C#不支持阴影那样。

究其原因o1再次工作,是它不影之前的o1



Answer 6:

这是相同的,与任何其它变量。 范围o是你的第一个整个表达式Where ,所以你不能在第二,这是第一个内再次使用它。 但是范围o1是刚刚在你的第二个表达Where ,这样你就可以在你的表达式中使用Max ,这是外面的第二Where 。 在代码:

// o scope lasts until the first bracket is closed
Where(o => o.CustomerID == customer.CustomerID && o.OrderDate ==
// o1 scope lasts until the second bracket is closed; the first is not yet closed here
        olist.Where(o1 => o1.CustomerID == customer.CustomerID)
// The second bracket is closed, so o1 is already out of scope; o is still in scope
             .Max(o1 => o1.OrderDate)
)
// The first bracket is closed, so o is finally out of scope


Answer 7:

我试着想象像这样按你的代码...

.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
    )

解释,但你的括号确定的范围,而粗暴的方式。 你的第二O1没有嵌套在第二个地方,其他明智的你有同样的问题里面

//outermost where

((BEGIN-o

//inner where

(BEGIN-o1 END-o1)

//max

(BEGIN-o1 END-o1)

END-o))


Answer 8:

var external = 1;

//This is a scope
Action scope = new Action(() =>
{
    //myVar is not accessible from outside
    var myVar = 0 + external;
    Console.WriteLine(myVar); //outputs 1
});

//Call the scope
scope();
//Console.WriteLine(myVar);//Will not compile

当代码被编译,所有从空隙中的逻辑在Action声明()=>{ ... }将被移动到在具有重整名称的类型的方法。

运行时间将调用新创建的功能时,它达到堆栈上那个地方。

您可以通过值成以各种方式范围/λ这是让他们出来的一样。

在一个lambda声明的变量是无法访问外与他们的声明的名称。

也可以利用反射拉出重整名称但我不知道你需要。 (请让我知道,如果我错了。)



文章来源: What is the scope of a lambda variable in C#?
标签: c# lambda scope