为什么 .net Framework 修改调用 Convert 函数的值类型的表达式?

Why .net Framework modify an expression for value types calling a Convert function?

我正在寻找解释而不是解决方案:这是我注意到的。 假设我有一个使用 Expression 的测试方法,如下所示。由于 Func 的返回 parameter"object",当我调用具有值类型 属性 (Test<TestClass>(x => x.SomeInt)) 的函数时,框架将我的表达式包装成 x=> Convert(x.SomeInt).Body 不再是 if type MemberExpression。难道是因为boxing/unboxing?但这是在哪里记录的。

    static void Test<TEntity>(Expression<Func<TEntity, object>> memberExpression)
    {
        //if value type, body is Convert(x.SomeInt)
        var body = memberExpression.Body.ToString();
    }

    class TestClass
    {
        public int SomeInt { get; set; }
        public string SomeString { get; set; }
    }

    static void Main(string[] args)
    {

        Test<TestClass>(x => x.SomeInt);
        Test<TestClass>(x => x.SomeString);
    }

因为 lambda 的类型是 T => object。当您将值类型转换为对象时,.NET 运行时需要做一些工作(创建值类型的盒装实例),因为转换。当您转换为引用类型时它不应该出现,因为转换 RefType => 对象不是操作。

您可以使用 Foo<T, TResult>(Expression<Func<T,TResult>> expr) 来改进您的代码。

由于表达式可以在运行时编译并从其结构中生成 CIL(.NET 字节码),因此他们引入了特殊节点以生成 CIL 装箱指令 box 或在用户定义的转换时调用方法执行自定义转换存在。这种方式的表达式反映了编译器生成的实际代码。