【问题标题】:C# Is there a way to resolve lambda expression`s delegate type in codeC# 有没有办法在代码中解析 lambda 表达式的委托类型
【发布时间】:2019-09-24 11:48:47
【问题描述】:

我的目标是支持应用程序中的排序并通过 REST API 公开它,该 API 将接受参数作为字符串。

目前的实现大致如下:

GetUsers (Expression<Func<User, int>> sortExpression) {
 // Retrieve users ... 
 return users.orderBy(sortExpression);
}

Usage example:
var users = GetUsers(u => u.Id);

Expression&lt;Func&lt;User, int&gt;&gt; sortExpression 在我们的存储库中被广泛使用,更改它会很困难。

我想做的是能够将u =&gt; u.Id 与运行时生成的东西交换。

到目前为止,我所拥有的是:

// sortBy is retrieved from the calling method.
var type = typeof(User).GetProperties().FirstOrDefault(x => x.Name == sortBy).GetType();

var sortExpression = Expression.Property(Expression.Parameter(typeof(User)), sortBy);

var parameter = Expression.Parameter(typeof(User));

var expressionBody = Expression.Lambda(typeof(Func<User, int>), sortExpression, parameter);

var users = GetUsers(expressionBody)

我可以在运行时看到这确实创建了一个符合我需要的表达式,但错误是 Argument 5: cannot convert from 'LambdaExpression' to 'Expression&lt;System.Func&lt;User, int&gt;&gt;',即使表达式的主体应该由 typeof(Func&lt;User, int&gt;) 设置

【问题讨论】:

  • 您只需要将LambdaExpression 转换为Expression&lt;Func&lt;User, int&gt;&gt;,例如:var expressionBody = (Expression&lt;Func&lt;User, int&gt;&gt;)Expression.Lambda(typeof(Func&lt;User, int&gt;), sortExpression, parameter);
  • 谢谢。我也完全错过了使用Expression.Lambda&lt;Func&lt;User, int&gt;&gt;(sortExpression, parameter); 创建表达式的通用方法

标签: c# generics lambda reflection


【解决方案1】:

我已经弄清楚我做错了什么。

首先:使用泛型方法创建表达式主体

// Generic Method, return type Expression<Func<User, int>>
Expression.Lambda<Func<User, int>>(sortExpression, parameter);

而不是传递typeof(Func&lt;User, int&gt;) 参数。

// Non-generic. Return type LambdaExpression
Expression.Lambda(typeof(Func<User, int>), sortExpression, parameter);

第二:

我没有正确绑定参数,这使得表达式正在访问未提供给表达式的废弃参数的属性。

// I'm creating an expression to access the property of a newly created parameter.
var sortExpression = Expression.Property(Expression.Parameter(typeof(User)), sortBy);
var parameter = Expression.Parameter(typeof(User));
var expressionBody = Expression.Lambda<Func<User, int>>(sortExpression, parameter);

//Above causes an unbinded variable exception since there are two parameters, one of which is not passed/bound.

//Should be:
var parameter = Expression.Parameter(typeof(User));
var sortExpression = Expression.Property(parameter, sortBy);

【讨论】:

    猜你喜欢
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    相关资源
    最近更新 更多