考虑下面的MyDecimal
课程。在C#
中,由于隐式decimal
运算符,我们可以将其转换为整数:
int i = (int)new MyDecimal(123m);
如何在表达式树中生成等效代码?
使用Expression.Convert(.NET 4.5.1
)时,它会立即失败并显示No coercion operator is defined between types 'System.Int32' and 'MyDecimal'
。它似乎只考虑隐式转换运算符。
try
{
var param = Expression.Parameter(typeof(int), null);
var convert = Expression.Convert(param, typeof(MyDecimal));
}
catch (Exception ex)
{
}
MyDecimal
上课:
public class MyDecimal
{
private readonly decimal value;
public MyDecimal(decimal value)
{
this.value = value;
}
public static implicit operator decimal(MyDecimal myDecimal)
{
return myDecimal.value;
}
public static implicit operator MyDecimal(decimal value)
{
return new MyDecimal(value);
}
}
答案 0 :(得分:4)
示例表达Lambda的表达式树的例子总是很有趣:
Expression<Func<MyDecimal,int>> convert = m => (int)m;
使用工具链接LinqPad,我们可以检查转换,看看我们有以下内容:
Expression<Func<MyDecimal,int>> (type: Lambda)
|
+- UnaryExpression (type:Convert) - Convert(int, decimal)
|
+- UnaryExpression (type:Convert) - Convert(decmal, MyDecimal)
因此,虽然编译器允许从decimal
到int
的隐式转换,但您可以看到等效的Lambda
要求转换是显式的。
<强> 修改 强>
因此,要构建完整的表达式,您需要具备以下内容:
Expression.Assign(
Expression.Variable(typeof(int), "i"),
Expression.Convert(
Expression.Convert(
Expression.New(
typeof(MyDecimal).GetConstructor(new[] {typeof(decimal)}),
Expression.Convert(
Expression.Constant(1),
typeof(decimal)
)
),
typeof(decimal)),
typeof(int)
)
)
需要注意的一些要点:
int
1转换为decimal
以传递给构造函数i
已经宣布。