次のコードを見てみましょう。
class Foo
{
string bar;
public void Method()
{
if (!String.IsNullOrEmpty(this.bar))
{
string bar = "Hello";
Console.Write(bar);
}
}
}
これはコンパイルされ、すべて問題ありません。ただし、this.
プレフィックスを削除しましょう。
class Foo
{
string bar;
public void Method()
{
if (!String.IsNullOrEmpty(bar)) // <-- Removed "this."
{
string bar = "Hello";
Console.Write(bar);
}
}
}
この場合、コンパイル エラーが発生します。これがエラーであることには同意しますが、私を混乱させるのはエラーの場所です。エラーは次の行で発生します。
string bar = "Hello";
メッセージ付き:
「bar」という名前のローカル変数をこのスコープで宣言することはできません。これは、「親または現在の」スコープで他の何かを示すために既に使用されている「bar」に別の意味を与えるためです。
コンパイラについて私が理解していることから、宣言はメソッドの先頭にbar
持ち上げられます。Method()
ただし、その場合は、次の行:
if (!String.IsNullOrEmpty(bar))
bar
インスタンスフィールドまたはまだ宣言されていないローカル変数への参照である可能性があるため、あいまいであると見なす必要があります。
私には、削除this.
すると別の行でコンパイルエラーが発生する可能性があるのは奇妙に思えます。言い換えれば、ローカルbar
変数の宣言は完全に有効ですが、スコープ内で以前に曖昧な参照が行われていない限りは有効です(コメントアウトするとエラーは消えます)。bar
if (!String.IsNullOrEmpty(bar))
それはすべてかなり衒学的に思えるので、あなたの質問は何ですか?:
私の質問は、コンパイラがスコープで宣言される前に変数へのあいまいな参照を許可するのに、宣言自体に冗長としてフラグを立てる理由です。bar
inへのあいまいな参照String.IsNullOrEmpty()
は、エラーのより正確な場所であるべきではありませんか? 私の例では、もちろん簡単に見つけることができますが、実際にこの問題に出くわしたとき、参照はページアップであり、追跡するのははるかに困難でした.