65

ラムダ変数のスコープについて混乱しています。たとえば、次のようになります。

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行目で再度宣言できないことを意味します(または、少なくともコンパイラーが文句を言います)が、「o1」がすでに存在していても3行目については文句を言いません。 ??

ラムダ変数のスコープは何ですか?

4

8 に答える 8

2

私はあなたのコードに従ってこのように描いてみます...

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

かなり大雑把な説明ですが、括弧が範囲を決定します。2 番目の o1 は 2 番目の内部にネストされていません。そうしないと、同じ問題が発生する可能性があります

//outermost where

((BEGIN-o

//inner where

(BEGIN-o1 END-o1)

//max

(BEGIN-o1 END-o1)

END-o))
于 2012-05-08T07:14:16.447 に答える
1
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 で宣言された void からのすべてのロジックが、マングルされた名前を持つ型のメソッドに移動されます。

ランタイムは、スタック上のその場所に到達すると、新しく作成された関数を呼び出します。

さまざまな方法で値をスコープ/ラムダに渡すことができます。これは、値を取得する場合と同じです。

ラムダで宣言された変数は、宣言された名前を使用して外部からアクセスすることはできません。

リフレクションを利用してマングルされた名前を引き出すことも可能ですが、それが必要かどうかはわかりません。(間違っていたら教えてください。)

于 2012-05-08T12:56:29.077 に答える