这是一个ExpressionTrees错误吗?#2

con*_*low 10 .net c# expression-trees

看起来ExpressionTrees编译器应该在许多行为中接近C#规范,但与C#不同,不支持从decimal任何行为转换enum-type:

using System;
using System.Linq.Expressions;

class Program
{
  static void Main()
  {
    Func<decimal, ConsoleColor> converter1 = x => (ConsoleColor) x;
    ConsoleColor c1 = converter1(7m); // fine

    Expression<Func<decimal, ConsoleColor>> expr = x => (ConsoleColor) x;

    // System.InvalidOperationException was unhandled
    // No coercion operator is defined between types
    // 'System.Decimal' and 'System.ConsoleColor'.

    Func<decimal, ConsoleColor> converter2 = expr.Compile();

    ConsoleColor c2 = converter2(7m);
  }
}
Run Code Online (Sandbox Code Playgroud)

其他很少使用的C#显式转换,如double -> enum-type存在,并按照C#规范中的说明工作,但不是decimal -> enum-type.这是一个错误吗?

Eri*_*ert 16

这可能是一个错误,这可能是我的错.对于那个很抱歉.

正确获得十进制转换是在编译器和运行时中构建表达式树代码最难的部分之一,因为十进制转换实际上是在运行时实现为用户定义的转换,但是被编译器视为内置转换.十进制是唯一具有此属性的类型,因此在这些情况下,分析仪中有各种专用齿轮.事实上,在分析器中有一个名为IsEnumToDecimalConversion的方法来处理可空的枚举到可以为空的十进制转换的特殊情况; 相当复杂的特殊情况.

赔率很高,我没有考虑到另一种情况,并因此产生了错误的代码.谢谢你的说明; 我会把这个发送给测试团队,我们会看看我们是否能得到一个重新开始.可能性很好,如果这确实是一个真正的错误,这将不适用于C#4初始版本; 在这一点上,我们只采取"用户被编译器触电"的错误,以便释放稳定.

  • @Brian:当你做一个表示改变转换时,比如int to double,有一条IL指令可以完成转换.当你做十进制加倍时,我们实际上生成代码来调用方法来进行转换; 没有用于小数的内置到CLR转换指令.但是从*语言*的角度来看,我们希望小数转换为***是内置到语言的转换; 我们对内置和用户提供的转换有不同的规则.因此,我们必须构建一些特殊的场景来隐藏具有小数的幕后发生的事情. (2认同)