【问题标题】:How does LambdaExpression resolve to Expression<Func<T, returnT>> at runtime via dynamic?LambdaExpression 如何在运行时通过动态解析为 Expression<Func<T, returnT>>?
【发布时间】:2016-10-25 19:40:56
【问题描述】:

我有一些工作代码,其中不同类型的Expression&lt;Func&lt;T, returnT&gt;&gt; 对象放在List&lt;LambdaExpression&gt; 中,然后在运行时通过使用dynamic 与接受Expression&lt;Func&lt;T, returnT&gt;&gt; 的方法匹配。这是我第一次使用dynamic,但我觉得我足够了解它的作用/功能。我很好奇的是从LambdaExpressionExpression&lt;Func&lt;T, returnT&gt;&gt; 的关系/分辨率。代码如下:

public void DoIt(Expression<Func<Record, string>> expr) { ... }
public void DoIt(Expression<Func<Record, int?>> expr) { ... }        
public void DoIt(Expression<Func<Record, DateTime?>> expr) { ... }


public class Record {
    public string Member1;
    public int? Member2;
    public DateTime? Member3;
}

Expression<Func<Record, string>> expr1 = r => r.Member1;
Expression<Func<Record, int?>> expr2 = r => r.Member2;
Expression<Func<Record, DateTime?>> expr3 = r => r.Member3;

var myList = new List<LambdaExpression>() {
    expr1, expr2, expr3
};

//later...

foreach (var expr in myList)
{
    DoIt((dynamic) expr);
    //What is happening w/ this LambdaExpression obj
    //so that it dispatches the appropriate DoIt method?
}

【问题讨论】:

  • 搜索动态调度。例如这里Dynamic Language Runtime Overview
  • 谢谢。我知道这是动态调度,但我想我认为在这种情况下动态的行为在某种程度上是 LambdaExpression 独有的。在阅读了更多关于它之后,现在我发现它不是。

标签: c# linq generics dynamic lambda


【解决方案1】:

Expression&lt;TDelegate&gt; 派生自 LambdaExpression

来自MSDN

在运行时,表示 lambda 的表达式树节点 表达式始终是 Expression 类型。

【讨论】:

    【解决方案2】:

    除了 Expression&lt;TDelegate&gt; 派生自 LambdaExpression 的事实 - 您正在将 LambdaExpression 转换为动态 - 它使用 DLR 来确定对象的类型。

    现在您的对象不是LambdaExpression,而是运行时的任何类型。由于您正在调用方法重载,因此它知道要调用哪个重载。

    当您使用静态类型 (var/LambdaExpression) 时,重载是在运行时确定的。在您的情况下,没有 LambdaExpression 重载,因此如果不转换为动态,它将无法编译。

    当使用动态类型时,重载是在运行时使用 DLR 确定的

    【讨论】:

      猜你喜欢
      • 2020-04-08
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多