2017-02-03 11 views
0

レットを使用すると、私はこのクラスを持っていると言う:メソッドシグネチャのパラメータ位置に依存するコンパイラエラー。未割り当てのローカル変数

class Boo 
{ 
    public override string ToString() 
    { 
     return "I am Boo!"; 
    } 
} 

これらの方法:メインで今

static int Foo(out Boo boo) 
{ 
    boo = new Boo(); 
    return 1; 
} 
static void Lol(Boo boo, int n) 
{ 
    Console.WriteLine(n); 
    Console.WriteLine(boo); 
} 

static void Main(string[] args) 
{ 
    Boo boo; 
    Lol(boo, Foo(out boo)); 
    Console.ReadLine(); 
} 

これはコンパイルエラーを与える:割り当てられていないローカル変数 'boo'の使用まず第一に、私はこれが起こっている理由を理解、私は追加することによって、それを修正することができます:

Boo boo = null; 

その後、私の方法では、booが最初に実行されているはFooにもかかわらず、ヌルのまま。

Lol(ref boo, Foo(out boo)); 
static void Lol(ref Boo boo, int n) 
{ 
    Console.WriteLine(n); 
    Console.WriteLine(boo); 
} 

私はブーだを得た:それから私はこのようREFを使用するように私のコードを変更した場合!のようになります。

static void Lol(int n, Boo boo) //order of the parameters has changed 
{ 
    Console.WriteLine(n); 
    Console.WriteLine(boo); 
} 

Lol(Foo(out boo), boo); 

が、これはコンパイル・エラーとI以外を与えるものではありません:私は理解していないことは、私は笑にとrefを使用せずにこのようブーイングを初期化せずにパラメータの順序を変更する場合は、なぜです"私はブー!"予想通り。

デバッグ中私は、両方の場合(最初のものとしてintパラメータを持ち、他の方法で)、Fooが最初に実行されることに気付きました。なぜコンパイラがこのエラーを表示しているのですか?

ありがとうございます!

+0

@ToastGeek、私が示したように変数を初期化する必要はありませんパラメータの順序を変更した後、すべてを読んでください、それは本当ではありません。期待通りの結果=) – taquion

答えて

3

コンパイラは、引数式を左から右に評価します。だから、この行に:(refなし)

Boo boo = null; 
Lol(boo,Foo(out boo)); 

boonullにもたらされる)最初に評価され、この結果null)はLolの引数としてスタックに置かれます。

Foo(out boo)ローカルboo変数の値を設定しますが、すでにスタック上にある値はLolに変更されません。 Fooによって変更としてあなたのローカルboo変数にref参照を使用して


がスタックに置かれているので、Lolは値を読み込みます。


パラメータの順序を変更する場合は、Foo(out boo)は/評価を最初に実行し、それの価値がLolのためにスタックに置かれる前にbooが初期化されています。

+0

ありがとう!それが理由を説明する!コンパイラがこれを解決し、エラーを投げないならば、それは良くないでしょうか?なぜなら、コンパイラがコンパイラをトリックするとしたら、Fooがどちらの場合でも最初に実行されるため、実行時エラーが発生しないからです。ただ言って... – taquion

関連する問題