【问题标题】:Lambda expression to initialize class with parameter and properties使用参数和属性初始化类的 Lambda 表达式
【发布时间】:2016-04-04 04:41:45
【问题描述】:

我有一个方法用于生成NewExpression

public NewExpression CreateNewExpression( Expression<Func<T>> expression )
{
    return expression.Body as NewExpression;
}

然后你可以做这样的事情。

CreateNewExpression( () => new MyType() );

稍后用于创建委托,可以执行该委托来创建对象。

var body = Expression.MemberInit( constructorExpression, bindings );
var funcType = typeof( Func<> ).MakeGenericType( objectType );
var lambda = Expression.Lambda( funcType, body ).Compile();

这很好用,但现在我想将一些数据传递到方法中,以便可以在对象的构造中使用。

public NewExpression CreateNewExpression( Expression<Func<T, Data>> expression )

然后会像这样使用它。

CreateNewExpression( data => new MyType( data.Id ) );

我这辈子都不知道如何创建正确的表达式来传递数据以供构造函数使用。

如果我不从 CreateNewExpression 中的表达式中提取正文并执行Expression.Invoke,我不知道如何设置属性。

如果我提取正文,我可以使用Expression.MemberInit 设置属性,但是我不知道如何将数据传递给它。

我该怎么做?

【问题讨论】:

  • 您能否详细说明您的目标?我认为在这里使用 Expressiont 树没有任何意义,你传入一个委托,它会做你想做的事,不是吗?
  • 我试图将其归结为基础。它被用于通过映射文件动态创建类对象。
  • 取一个表达式只是为了取出主体,然后重构它并编译在我看来并不是什么有用的东西。此外,在您尝试使用参数的情况下,只需获取正文,您就会失去对参数的引用。你能发布你想要的 API 吗?或者至少是一个示例用法?有一些示例类请
  • 在这个库中使用。如果你有更好的方法,我很想知道。 github.com/JoshClose/CsvHelper/tree/master/src/CsvHelper

标签: c# lambda expression-trees


【解决方案1】:

当您想使用包含ParameterExpression 的表达式时,您也需要在最终表达式中重复使用相同的ParameterExpression

为此,您可以访问原始表达式的Parameters,然后将参数传递给Expression.Lambda()。结果可能如下所示:

public Delegate M<T>(Expression<Func<Data, T>> expression)
{
    var objectType = typeof(T);

    var constructorExpression = (NewExpression)expression.Body;
    var constructorParameterExpression = expression.Parameters.Single();

    var bindings = …;

    var body = Expression.MemberInit( constructorExpression, bindings );
    var funcType = typeof( Func<,> ).MakeGenericType( typeof(Data), objectType );
    var lambda = Expression.Lambda( funcType, body, constructorParameterExpression )
        .Compile();

    return lambda;
}

【讨论】:

  • 非常感谢!我确实有这个,但没有传递原始的构造函数参数表达式。我尝试创建一个新的。这很好用。
【解决方案2】:

我认为您的问题的答案可能是Expression.Parameter

我在geeks with blogs 上找到了一个使用此功能的博客条目。此解决方案的唯一缺点是,当您需要三个以上的参数时,您必须创建新的重载。但我想这可以通过params object[] 轻松解决。

【讨论】:

    猜你喜欢
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多