【问题标题】:How do I build an expression with a certain signature?如何构建具有特定签名的表达式?
【发布时间】:2015-01-13 18:03:47
【问题描述】:

我正在尝试使用Expression<Func<T, string>> 类型的参数调用方法,但我构建的表达式树不允许我调用该方法。这是一个简短但完整的程序来演示该问题:

using System;
using System.Linq.Expressions;

public class Test
{
    public string Name { get { return ""; } }

    public static void Main()
    {
        Foo<Test>();
    }

    static void Foo<T>()
    {
        var parameter = Expression.Parameter(typeof(T), "t");
        var property = Expression.Property(parameter, "Name");
        var lambda = Expression.Lambda(property, parameter);
        Bar<T>(lambda);
    }

    static void Bar<T>(Expression<Func<T, string>> expression) {}
}

错误:

error CS1503: Argument 1: cannot convert from
'System.Linq.Expressions.LambdaExpression' to 
'System.Linq.Expressions.Expression<System.Func<T, string>>'

如何将我的表达式树传递给方法?

【问题讨论】:

    标签: c# lambda expression-trees


    【解决方案1】:

    您实际上已经在构建一个表达式树,它在 执行 时具有正确的类型(如果您只是不尝试调用该方法,并打印出要执行的对象的类型) lambda 的值是指)。但是,lambda 的编译时类型只是LambdaExpression,而不是Expression&lt;Func&lt;T, string&gt;&gt;。那是因为您使用了非泛型重载 Expression.Lambda,该重载旨在在您在编译时知道所需的表达式树类型时使用。这在执行时做了正确的事情,但不允许您以强类型的方式使用它。

    幸运的是,您确实知道要生成的表达式树的类型,因此您只需在调用 Expression.Lambda 的泛型重载时指定它:

    var lambda = Expression.Lambda<Func<T, string>>(property, parameter);
    

    如果你建立的表达式树没有正确的类型,这将在执行时抛出异常,例如如果Value1 属性类型错误。

    【讨论】:

      【解决方案2】:

      lambda 构建不正确。

      var parameter = Expression.Parameter(typeof(T), "t");
      var property = Expression.Property(parameter, "Value1");
      var lambda = Expression.Lambda<Func<T, string>>(property, new[] { parameter });
      

      【讨论】:

        猜你喜欢
        • 2018-12-16
        • 2022-10-13
        • 2012-12-22
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多