这是一个ExpressionTrees错误吗?

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

using System;
using System.Linq.Expressions;

class Program
{
  static void Main()
  {
    Expression<Func<float, uint>> expr = x => (uint) x;

    Func<float,uint> converter1 = expr.Compile();
    Func<float,uint> converter2 = x => (uint) x;

    var aa = converter1(float.MaxValue); // == 2147483648
    var bb = converter2(float.MaxValue); // == 0
  }
}
Run Code Online (Sandbox Code Playgroud)

编译Expression.Convert此转换时可以建立相同的不同行为:

Single -> UInt32 Single -> UInt64

Double -> UInt32 Double -> UInt64

看起来很奇怪,不是吗?

<===添加了一些我的研究===>

我看了DynamicMethod使用DynamicMethod Visualizer编译的MSIL代码和一些反射hack来DynamicMethod从编译中获取Expression<TDelegate>:

Expression<Func<float, uint>> expr = x => (uint) x;

Func<float,uint> converter1 = expr.Compile();
Func<float,uint> converter2 = x => (uint) x;

// get RTDynamicMethod - compiled MethodInfo
var rtMethodInfo = converter1.Method.GetType();

// get the field with the reference
var ownerField = rtMethodInfo.GetField(
  "m_owner", BindingFlags.NonPublic | BindingFlags.Instance);

// get the reference to the original DynamicMethod
var dynMethod = (DynamicMethod) ownerField.GetValue(converter1.Method);

// show me the MSIL
DynamicMethodVisualizer.Visualizer.Show(dynMethod);
Run Code Online (Sandbox Code Playgroud)

我得到的是这个MSIL代码:

IL_0000: ldarg.1
IL_0001: conv.i4
IL_0002: ret
Run Code Online (Sandbox Code Playgroud)

并且相同的C#编译方法有这个主体:

IL_0000: ldarg.0
IL_0001: conv.u4
IL_0002: ret
Run Code Online (Sandbox Code Playgroud)

现在有人看到ExpressionTrees编译这个转换的有效代码吗?

Eri*_*ert 11

显然是一个错误,它在今天的C#4.0版本中重现.感谢您提请我们注意.在最终版本发布之前,这个问题不会成为解决问题的障碍; 在这个最后阶段,我们只采取了非常高优先级的解决方案,我们有信心不会破坏发布的稳定性.更有可能的是,修复将使其成为未来的服务版本; 但当然,没有承诺.