Weird C# compiler issue with variable name ambiguity
<p>Let's take the following code:</p>

<pre><code>class Foo
{
   string bar;

   public void Method()
   {
      if (!String.IsNullOrEmpty(this.bar))
      {
         string bar = "Hello";
         Console.Write(bar);
      }
   }
}
</code></pre>

<p>This will compile, and all is good.  However, let's now remove the <code>this.</code> prefix:</p>

<pre><code>class Foo
{
   string bar;

   public void Method()
   {
      if (!String.IsNullOrEmpty(bar)) // &lt;-- No more this.
      {
         string bar = "Hello";
         Console.Write(bar);
      }
   }
}
</code></pre>

<p>In this case, I get a compiler error.  I agree this is an error, however it's the location of the error that confuses me.  The error happens on the line:</p>

<pre><code>string bar = "Hello";
</code></pre>

<p>With the message:</p>

<blockquote>
  <p>A local variable named 'bar' cannot be declared in this scope because
  it would give a different meaning to 'bar', which is already used in a
  'parent or current' scope to denote something else</p>
</blockquote>

<p>From what I understand about the compiler, the declaration of <code>bar</code> gets <em>hoisted</em> to the top of the <code>Method()</code> method.  However, if that's the case, the line:</p>

<pre><code>if (!String.IsNullOrEmpty(bar))
</code></pre>

<p>Should be considered ambiguous, as <code>bar</code> could be a reference to the instance field or to the not-yet-declared local variable.</p>

<p>To me, it seems odd that removing <code>this.</code> can cause a compilation error on another line.  In other words, declaring a local <code>bar</code> variable is perfectly valid, <em>as long as</em> no potentially <em>ambiguous</em> references to <code>bar</code> have been made previously in the scope (note, if I comment out <code>if (!String.IsNullOrEmpty(bar))</code> then the error goes away).</p>

<p><strong>That all seems rather pedantic, so what's your question?:</strong></p>

<p>My question is why the compiler allows an ambiguous reference to a variable before it's declared in the scope, but then flags the declaration itself as <em>redundant</em>.  Shouldn't the ambiguous reference to <code>bar</code> in <code>String.IsNullOrEmpty()</code> be a more precise location of the error?  In my example, it's of course easy to spot, but when I ran across this issue in the wild, the reference was pages up and much harder to track down.</p>
