Выполняя следующие действия, я получаю простую лямбду для суммирования двух целых чисел:
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);
Теперь, как мне пометить параметры лямбды атрибутами? Это удобно, например, когда вы хотите динамически генерировать конечные точки минимального приложения API и вам нужно пометить параметры с помощью [FromServices]. Могу ли я создать подобную лямбду, используя деревья выражений?
([FromServices] ISender sender, [FromBody] LoginDto body, CancellationToken ct) =>
sender.Send(new LoginQuery(body), ct)
Я ничего не могу найти ни в Expression.Parameter(), ни в каких-либо других фабричных методах класса Expression.
Но подобное решение позволило бы мне свернуть уровень конечных точек/контроллера с помощью CQRS, избегая большого количества шаблонов (поскольку первый мало что делает).
Для TypeBuilder см., например. Программно добавьте атрибут к методу или параметру. У меня сложилось впечатление, что этот класс непросто использовать.





В настоящее время это невозможно. Деревья выражений не могут содержать атрибуты. Компилятор явно сообщает вам об этом, когда вы пытаетесь скомпилировать что-то вроде этого:
Expression<Func<int, int>> e = ([Foo] x) => x;
public class FooAttribute: Attribute { }
В сообщении об ошибке говорится:
CS8972: лямбда-выражение с атрибутами невозможно преобразовать в дерево выражений.
Я не могу найти в LDM ничего, что объясняло бы, почему это не поддерживается, но теоретически деревья выражений могут полностью включать информацию об атрибутах — это будет просто еще один узел дерева.
Метаданные, такие как
[FromServices], являются статическими и применяются к типам. Например, FromServicesAttribute имеет[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, ...)]. Я был бы рад, если бы меня доказали, что я ошибаюсь, но я не могу себе представить, как вы могли бы сделать это с выражениями, которые создают экземпляры делегатов, а не типы. Может быть, вам понадобится TypeBuilder?