【问题标题】:Can i traverse a expression bodied member with an ExpressionVisitor?我可以使用 ExpressionVisitor 遍历表达式主体成员吗?
【发布时间】:2021-10-23 08:54:29
【问题描述】:

我有以下数据结构:

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 的 Expression。构建对远程系统的请求。

有没有办法(通过反射?)访问表达式 bodyed member getter's Expression?

【问题讨论】:

  • 不,表达式主体成员只是语法糖。
  • 您能否提供文件以确认您的陈述并将其作为答案发布?我很乐意接受它作为答案!

标签: c# linq expression expression-trees


【解决方案1】:

您不能遍历表达式体属性的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
}

如果您使用块体属性,则会生成相同的代码。如您所见,任何地方都没有Expressions。你可以在 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);

【讨论】:

  • 感谢您的出色回答。它回答了我的问题并提供了一个不错的选择!
猜你喜欢
  • 2013-01-17
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多