title: Curious null-coalescing operator custom implicit conversion behaviour
body: <p><strong>Note: this appears to have been fixed in <a href="https://github.com/dotnet/roslyn" rel="noreferrer">Roslyn</a></strong></p>
  
  <p>This question arose when writing my answer to <a href="https://stackoverflow.com/questions/6238074">this one</a>, which talks about the associativity of the <a href="http://msdn.microsoft.com/en-us/library/ms173224.aspx" rel="noreferrer">null-coalescing operator</a>.</p>
  
  <p>Just as a reminder, the idea of the null-coalescing operator is that an expression of the form</p>
  
  <pre><code>x ?? y
  </code></pre>
  
  <p>first evaluates <code>x</code>, then:</p>
  
  <ul>
  <li>If the value of <code>x</code> is null, <code>y</code> is evaluated and that is the end result of the expression</li>
  <li>If the value of <code>x</code> is non-null, <code>y</code> is <em>not</em> evaluated, and the value of <code>x</code> is the end result of the expression, after a conversion to the compile-time type of <code>y</code> if necessary</li>
  </ul>
  
  <p>Now <em>usually</em> there's no need for a conversion, or it's just from a nullable type to a non-nullable one - usually the types are the same, or just from (say) <code>int?</code> to <code>int</code>. However, you <em>can</em> create your own implicit conversion operators, and those are used where necessary.</p>
  
  <p>For the simple case of <code>x ?? y</code>, I haven't seen any odd behaviour. However, with <code>(x ?? y) ?? z</code> I see some confusing behaviour.</p>
  
  <p>Here's a short but complete test program - the results are in the comments:</p>
  
  <pre><code>using System;
  
  public struct A
  {
      public static implicit operator B(A input)
      {
          Console.WriteLine("A to B");
          return new B();
      }
  
      public static implicit operator C(A input)
      {
          Console.WriteLine("A to C");
          return new C();
      }
  }
  
  public struct B
  {
      public static implicit operator C(B input)
      {
          Console.WriteLine("B to C");
          return new C();
      }
  }
  
  public struct C {}
  
  class Test
  {
      static void Main()
      {
          A? x = new A();
          B? y = new B();
          C? z = new C();
          C zNotNull = new C();
  
          Console.WriteLine("First case");
          // This prints
          // A to B
          // A to B
          // B to C
          C? first = (x ?? y) ?? z;
  
          Console.WriteLine("Second case");
          // This prints
          // A to B
          // B to C
          var tmp = x ?? y;
          C? second = tmp ?? z;
  
          Console.WriteLine("Third case");
          // This prints
          // A to B
          // B to C
          C? third = (x ?? y) ?? zNotNull;
      }
  }
  </code></pre>
  
  <p>So we have three custom value types, <code>A</code>, <code>B</code> and <code>C</code>, with conversions from A to B, A to C, and B to C.</p>
  
  <p>I can understand both the second case and the third case... but <em>why</em> is there an extra A to B conversion in the first case? In particular, I'd <em>really</em> have expected the first case and second case to be the same thing - it's just extracting an expression into a local variable, after all.</p>
  
  <p>Any takers on what's going on? I'm extremely hesistant to cry "bug" when it comes to the C# compiler, but I'm stumped as to what's going on...</p>
  
  <p>EDIT: Okay, here's a nastier example of what's going on, thanks to configurator's answer, which gives me further reason to think it's a bug. EDIT: The sample doesn't even need two null-coalescing operators now...</p>
  
  <pre><code>using System;
  
  public struct A
  {
      public static implicit operator int(A input)
      {
          Console.WriteLine("A to int");
          return 10;
      }
  }
  
  class Test
  {
      static A? Foo()
      {
          Console.WriteLine("Foo() called");
          return new A();
      }
  
      static void Main()
      {
          int? y = 10;
  
          int? result = Foo() ?? y;
      }
  }
  </code></pre>
  
  <p>The output of this is:</p>
  
  <pre><code>Foo() called
  Foo() called
  A to int
  </code></pre>
  
  <p>The fact that <code>Foo()</code> gets called twice here is hugely surprising to me - I can't see any reason for the expression to be <em>evaluated</em> twice.</p>