我可以使用 ExpressionVisitor 遍历表达式主体成员吗?
Can i traverse a expression bodied member with an ExpressionVisitor?
我有以下数据结构:
class OrderLine : Table
{
public int Id { get; set; }
public Order Order { get; set; }
public decimal Quantity { get; set; }
public decimal UnitPrice { get; set; }
[CalculatedField]
public decimal LinePrice {
get => Quantity * LinePrice;
}
}
我想用 ExpressionVisitor 遍历 LinePrice getter 的表达式。构建对远程系统的请求。
有没有办法(通过反射?)访问表达式主体成员 getter 的表达式?
您不能遍历表达式主体属性的 Expression
,因为它们不是 Expression
对象。表达式体属性与其他属性没有什么不同,除了它们的语法。您的 属性 在这里:
public decimal LinePrice {
get => Quantity * LinePrice; // did you mean UnitPrice?
}
编译成:(如SharpLab上所见)
.method public hidebysig specialname
instance valuetype [System.Private.CoreLib]System.Decimal get_LinePrice () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance valuetype [System.Private.CoreLib]System.Decimal OrderLine::get_Quantity()
IL_0006: ldarg.0
IL_0007: call instance valuetype [System.Private.CoreLib]System.Decimal OrderLine::get_LinePrice()
IL_000c: call valuetype [System.Private.CoreLib]System.Decimal [System.Private.CoreLib]System.Decimal::op_Multiply(valuetype [System.Private.CoreLib]System.Decimal, valuetype [System.Private.CoreLib]System.Decimal)
IL_0011: ret
}
如果您使用块体属性,将生成相同的代码。如您所见,任何地方都没有 Expression
。你可以在 SharpLab 上试试这个。这表明表达式体成员是纯粹的语法糖。
如果你想把它作为一个 Expression
遍历,你实际上应该声明一个 Expression
:
// now you can traverse this with ExpressionVisitor
public static readonly Expression<Func<OrderLine, decimal>> LinePriceExpression
= x => x.Quantity * x.UnitPrice;
// to avoid repeating "Quantity * UnitPrice" again in the property getter,
// you can compile the expression and reuse it
private static readonly Func<OrderLine, decimal> LinePriceExpressionCompiled
= LinePriceExpression.Compile();
public decimal LinePrice => LinePriceExpressionCompiled(this);
我有以下数据结构:
class OrderLine : Table
{
public int Id { get; set; }
public Order Order { get; set; }
public decimal Quantity { get; set; }
public decimal UnitPrice { get; set; }
[CalculatedField]
public decimal LinePrice {
get => Quantity * LinePrice;
}
}
我想用 ExpressionVisitor 遍历 LinePrice getter 的表达式。构建对远程系统的请求。
有没有办法(通过反射?)访问表达式主体成员 getter 的表达式?
您不能遍历表达式主体属性的 Expression
,因为它们不是 Expression
对象。表达式体属性与其他属性没有什么不同,除了它们的语法。您的 属性 在这里:
public decimal LinePrice {
get => Quantity * LinePrice; // did you mean UnitPrice?
}
编译成:(如SharpLab上所见)
.method public hidebysig specialname
instance valuetype [System.Private.CoreLib]System.Decimal get_LinePrice () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance valuetype [System.Private.CoreLib]System.Decimal OrderLine::get_Quantity()
IL_0006: ldarg.0
IL_0007: call instance valuetype [System.Private.CoreLib]System.Decimal OrderLine::get_LinePrice()
IL_000c: call valuetype [System.Private.CoreLib]System.Decimal [System.Private.CoreLib]System.Decimal::op_Multiply(valuetype [System.Private.CoreLib]System.Decimal, valuetype [System.Private.CoreLib]System.Decimal)
IL_0011: ret
}
如果您使用块体属性,将生成相同的代码。如您所见,任何地方都没有 Expression
。你可以在 SharpLab 上试试这个。这表明表达式体成员是纯粹的语法糖。
如果你想把它作为一个 Expression
遍历,你实际上应该声明一个 Expression
:
// now you can traverse this with ExpressionVisitor
public static readonly Expression<Func<OrderLine, decimal>> LinePriceExpression
= x => x.Quantity * x.UnitPrice;
// to avoid repeating "Quantity * UnitPrice" again in the property getter,
// you can compile the expression and reuse it
private static readonly Func<OrderLine, decimal> LinePriceExpressionCompiled
= LinePriceExpression.Compile();
public decimal LinePrice => LinePriceExpressionCompiled(this);