views:

98

answers:

1

This is not "close to real" situation, but it shows that Expressions API doesn't look for operators in the destination type of conversion if it founds the suitable operator in the source type.

sealed class Foo
{
  public static explicit operator Bar(Foo foo) { return null; }
}

sealed class Bar
{
  public static implicit operator Bar(Foo foo) { return null; }
}

class Program
{
  public static void Blah(Bar bar) { }

  private static void Main()
  {
    Expression<Func<Foo, Bar>> expr1 = x => x;

    // fine, used implicit operator from Bar

    var param = Expression.Parameter(typeof(Foo), "x");

    var expr2 = Expression.Lambda<Func<Foo, Bar>>(
      Expression.Convert(param, typeof(Bar)),
      param);

    // fine, but used explicit operator from Foo!
  }
}

Also if simulate ambiguity between user-defined operators in the two types, C# compiler doesn't compile conversion at all, but the Expressions API will use operator from the conversion source type.

+4  A: 

No, it's not an expression tree bug. If you fail to supply enough information for the expression tree library to do what you want, then you'll just have to accept its defaults. There is no reason whatsoever that those defaults need to follow the rules of C#; the expression tree libraries are not a C# compiler.

Eric Lippert