Как пометить параметр атрибутом в динамически создаваемом лямбда-выражении?

Выполняя следующие действия, я получаю простую лямбду для суммирования двух целых чисел:

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, избегая большого количества шаблонов (поскольку первый мало что делает).

Метаданные, такие как [FromServices], являются статическими и применяются к типам. Например, FromServicesAttribute имеет [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, ...)]. Я был бы рад, если бы меня доказали, что я ошибаюсь, но я не могу себе представить, как вы могли бы сделать это с выражениями, которые создают экземпляры делегатов, а не типы. Может быть, вам понадобится TypeBuilder?

dbc 05.05.2024 22:51

Для TypeBuilder см., например. Программно добавьте атрибут к методу или параметру. У меня сложилось впечатление, что этот класс непросто использовать.

dbc 05.05.2024 22:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В настоящее время это невозможно. Деревья выражений не могут содержать атрибуты. Компилятор явно сообщает вам об этом, когда вы пытаетесь скомпилировать что-то вроде этого:

Expression<Func<int, int>> e = ([Foo] x) => x;

public class FooAttribute: Attribute { }

В сообщении об ошибке говорится:

CS8972: лямбда-выражение с атрибутами невозможно преобразовать в дерево выражений.

Я не могу найти в LDM ничего, что объясняло бы, почему это не поддерживается, но теоретически деревья выражений могут полностью включать информацию об атрибутах — это будет просто еще один узел дерева.

Другие вопросы по теме

Похожие вопросы

Когда я пытаюсь построить Docker, я получаю, что каждый из моих проектов csharp не может вычислить кеш (то есть не может быть найден)
Эквивалент ConfigurationApiBehaviorOptions() для минимальных API
Уменьшите количество условных операторов (4), используемых в выражении (максимум 3) в предикате Expression<Func<T,bool>
Microsoft.Office.Interop.Excel не работает после перехода на PackageReference
Регулярное выражение не разбивает строку, разделенную точкой с запятой, в C#, если первое совпадение пусто
Как изменить громкость преобразования текста в речь для объектов SpeechSynthesizer в Azure CognitiveServices SDK без изменения громкости системы в С#
IText7 Как получить расположение текстов в формате классических китайских документов?
Метод расписания HangFire не срабатывает при использовании с Enqueue внутри сервера BackgroundJib
.net MAUI Как получить кроссплатформенность DPi/PPi
Какие значения может возвращать Environment.SystemDirectory?