执行以下操作,我获得了一个简单的 lambda 来对两个整数求和:
using System.Linq.Expressions;
var xParam = Expression.Parameter(typeof(int), "x");
var yParam = Expression.Parameter(typeof(int), "y");
var sum = Expression.Add(xParam, yParam);
var lambda = Expression.Lambda<Func<int, int, int>>(sum, [xParam, yParam]);
var func = lambda.Compile();
var result = func(1, 2);
这相当于拥有这个:
var func = (x, y) => x + y;
var result = func(1, 2);
现在,如何用属性标记 lambda 的参数? 例如,当您想要动态生成最小 API 应用程序的端点并且需要使用 [FromServices] 标记参数时,这会派上用场。我可以使用表达式树生成这样的 lambda 吗?
([FromServices] ISender sender, [FromBody] LoginDto body, CancellationToken ct) =>
sender.Send(new LoginQuery(body), ct)
我找不到任何东西,无论是在
Expression.Parameter()
上,还是 Expression
类的任何其他工厂方法。
但是这样的解决方案可以让我用 CQRS 折叠端点/控制器层,从而避免大量样板文件(因为前者没有做太多事情)。
目前这是不可能的。表达式树不能包含属性。当您尝试编译如下内容时,编译器会明确告诉您这一点:
Expression<Func<int, int>> e = ([Foo] x) => x;
public class FooAttribute: Attribute { }
错误消息显示:
CS8972:带有属性的 lambda 表达式无法转换为表达式树
我在 LDMs 中找不到任何内容来解释为什么不支持这一点,但理论上,表达式树可以完全包含有关属性的信息 - 它只是另一个树节点。