2012-02-12 6 views
1

誰かが私にどのように機能するのか教えてもらえますか?私は感謝されます。ダンノーはこれをデバッグする方法。なぜこのコードが109を返しますか?

using System; 

    class Prg 
    { 
     private static Func<double, Func<double, double>> Add(int c) 
     { 
      return x => y => x + y++ + (c *= 2); 
     } 

     public static void Main(string[] args) 
     { 
      int a = 1; 
      int b = 100; 
      var F = Add(2); 
      var G = F(a); 
      G(b); 
      Console.WriteLine(G(b)); 
     } 
    } 

EDIT:私たちのC#試験を楽しんでいただければもう1つあります。ここにコードがあります。

delegate int F(); 
class Prg { int a = 10; 
    public F Adder(int x) { 
    int i = x; 
    return delegate { 
     return a += i++; }; 
    } 
    static void Main() { 
    Prg p = new Prg(); 
    F f = p.Adder(5); 
    p.Adder(10); 
    f(); 
    System.Console.Write(f()); 
} } 
+2

この記事のなか見!いくつかの曖昧なコードの課題? – Dykam

+0

ダイカムがポイントを作った。 「家では絶対試してはいけない!しかし、ラムダによって割り当てられて参照されるメモリ変数の特定の動作を指摘したい場合は、もっと良い例を作ることができます。 – doblak

+0

これは私が持っているC#の試験の仕事の一つです。 – user378653

答えて

3

私は次のように始めます:このようなコードを書かないでください。

そして、あなたが本当に何が起こっているか知りたい場合:

ライン var F = Add(2)
  1. 、この方法は、(追加)を作成し、C == 2とラムダ式を返します。何、ここで重要なことは、あなたがmsdnに変数をキャプチャについて読むことができます(cはラムダによって捕捉されていることである。ラインで
  2. 正確にはあなたは、単にパラメータa = 1であなたの関数を呼び出していると、あなたが結果として別の関数を取得し、double -> doublevar G = F(x) 。ラインで
  3. あなたはあなたの関数を呼び出しているG(b)、まさにこの1:x + y++ + (c *= 2);今:
    • xは1つの
    • yに等しいあなたのパラメータであり、それはに等しい100
    • cが2に等しく、実際には割り当てられたフィールドへの参照です
    • この式の結果は105です(100 ++は100を返し、2 * = 2は4を返します)。したがって、1 + 100 + 4 = 105となります。しかし、より重要なのは、変数cがキャプチャであることは4になりました.yは単なるパラメータなので変更されませんでした。
  4. Console....では、関数を再度呼び出しています。今回は、パラメータがその結果は同じになり、100に再び同じであるが、あなたの捕獲変数cはそうあなたが1 + (100+) + (4 *= 2) -> 1 + 100 + 8 -> 109

を受けた結果がここにいくつかの光を当てるかもしれない簡単な例ですが、今4に等しく、何が起こったのですか:

class Prg 
{ 
    public static void Main(string[] args) 
    { 
     int captured = 5; 
     int param = 3; 

     var func = new Func<int, int>(x => x * captured); 

     Console.WriteLine(func(param)); 
     captured = 6; 
     Console.WriteLine(func(param)); 

    } 
} 
2

この部分は二回実行されます。

c *= 2 

あなたは(b)のGを呼び出し初めて。コンソールに印刷する2回目。

一つの実行は、実際に計算します。

a + b++ + (c *= 2) 

をしかし、cが2を乗じた(とバックCに割り当てられている)各実行時に取得しているので、あなたの代わりに105 変数cの109を得るには1つの正確なメモリとして参照されていますFuncの代理人として実際に使用されています(Funcのインスタンスは常に同じままです)。そのため、関数でネストされた呼び出しを行う場合と同じではありません(ここでは、値が返され、関数のスコープが閉じられ、同じコンテキストで再度アクセスされることはありません)。

関連する問題