title: Why is 'is' implemented as 'as'?
body: <p>Given that this is a very natural use case (if you don't know what <code>as</code> actually does),</p>
  
  <pre><code>if (x is Bar) {
     Bar y = x as Bar;
     something();
  }
  </code></pre>
  
  <p>is effectively equivalent (that is, the compiler-generated <a href="http://en.wikipedia.org/wiki/Common_Intermediate_Language" rel="nofollow noreferrer">CIL</a> from the above code will be equivalent) to:</p>
  
  <pre><code>Bar y = x as Bar;
  if (y != null) {
      y = x as Bar; //The conversion is done twice!
      something();
  }
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I guess I hadn't made my question clear. I wouldn't ever write the second snippet as it's of course redundant. I'm claiming that the CIL generated by the compiler when compiling the first snippet is equivalent to the second snippet, which is redundant. Questions: a) Is this correct? b) If so, why is <code>is</code> implemented like that?</p>
  
  <p>This is because I find the first snippet a lot clearer and prettier than the actually well-written</p>
  
  <pre><code>Bar y = x as Bar;
  if (y != null) {
     something();
  }
  </code></pre>
  
  <p><strong>CONCLUSION:</strong></p>
  
  <p>Optimizing the <code>is</code>/<code>as</code> case is not the compiler's responsibility, but the JIT's.</p>
  
  <p>Also, as with a null check it has fewer (and less expensive) instructions than both of the alternatives (<code>is</code> and <code>as</code> and <code>is</code> and <code>cast</code>).</p>
  
  <p>Addendum:</p>
  
  <p>CIL for as with nullcheck (.NET 3.5):</p>
  
  <pre><code>L_0001: ldarg.1
  L_0002: isinst string
  L_0007: stloc.0
  L_0008: ldloc.0
  L_0009: ldnull
  L_000a: ceq
  L_000c: stloc.1
  L_000d: ldloc.1
  L_000e: brtrue.s L_0019
  L_0011: ldarg.0
  L_0019: ret
  </code></pre>
  
  <p>CIL for is and cast (.NET 3.5):</p>
  
  <pre><code>L_0001: ldarg.1
  L_0002: isinst string
  L_0007: ldnull
  L_0008: cgt.un
  L_000a: ldc.i4.0
  L_000b: ceq
  L_000d: stloc.1
  L_000e: ldloc.1
  L_000f: brtrue.s L_0021
  L_0012: ldarg.1
  L_0013: castclass string
  L_0018: stloc.0
  L_0019: ldarg.0
  L_0021: ret
  </code></pre>
  
  <p>CIL for is and as (.NET 3.5):</p>
  
  <pre><code>L_0001: ldarg.1
  L_0002: isinst string
  L_0007: ldnull
  L_0008: cgt.un
  L_000a: ldc.i4.0
  L_000b: ceq
  L_000d: stloc.1
  L_000e: ldloc.1
  L_000f: brtrue.s L_0021
  L_0012: ldarg.1
  L_0013: isinst string
  L_0018: stloc.0
  L_0019: ldarg.0
  L_0021: ret
  </code></pre>
  
  <p>These have been edited for shortness (method declarations, nops and calls to something() removed).</p>