【问题标题】:How to pass object of type LambdaExpression to methods that only accept Expression<Func<T, retT>>?如何将 LambdaExpression 类型的对象传递给只接受 Expression<Func<T, retT>> 的方法?
【发布时间】:2015-07-31 20:54:19
【问题描述】:

我有一些具有不同返回类型的表达式存储在List&lt;LambdaExpression&gt; 中。我需要能够将这些表达式传递给一组我无法控制但只接受Expression&lt;Func&lt;T, retT&gt;&gt; 类型的参数的方法。任何想法我怎么能做到这一点?示例代码如下:

//These 3 methods are not under my control, can't change them :(
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(expr); 
}

【问题讨论】:

  • 你在写doit吗?
  • 不,我不能改变它。
  • MarcinJuraszek 解决方案是正确的。

标签: c# generics lambda


【解决方案1】:

你可以试试dynamic:

foreach (var expr in myList)
{
    DoIt((dynamic)expr); 
}

它将根据expr的实际类型在运行时强制方法重载解析发生,只要有合适的DoIt方法被调用,它就会起作用。

【讨论】:

  • 啊,我们走了。那行得通。好像dynamic 最近经常来救我:) 谢谢!
【解决方案2】:

一个需要最少代码更改的简单解决方案是调用动态重载解决方案。您失去了任何类型安全性,但根据您的要求,您似乎已经失去了它。

foreach (dynamic expr in myList) {
    DoIt(expr); 
}

这将重载决议从编译时转移到运行时。这意味着如果解析失败,您会得到一个抛出的异常而不是构建失败。但是,我认为这个问题的任何解决方案都将不可避免地出现这个缺点,因为有很多 LambdaExpressions 不是由 DoIt 方法处理的。

【讨论】:

    【解决方案3】:

    MarcinJuraszek 和递归的答案都是正确的。虽然如果你想在没有动态的情况下这样做,你可以这样做:

    foreach (var expr in myList)
    {
        if (expr.ReturnType == typeof (string))
            DoIt((Expression<Func<Record, string>>) expr);
        else if (expr.ReturnType == typeof (int?))
            DoIt((Expression<Func<Record, int?>>) expr);
        else if (expr.ReturnType == typeof (DateTime?))
            DoIt((Expression<Func<Record, DateTime?>>) expr);
    }
    

    【讨论】:

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