为什么 .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
或在用户定义的转换时调用方法执行自定义转换存在。这种方式的表达式反映了编译器生成的实际代码。
我正在寻找解释而不是解决方案:这是我注意到的。
假设我有一个使用 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
或在用户定义的转换时调用方法执行自定义转换存在。这种方式的表达式反映了编译器生成的实际代码。