Можно ли извлечь свойства и значения из Action<T>?

Сначала я определил класс, например:

class UserInfo
{
    public string UserName { get; set; }
    public int Age { get; set; }
    public bool State { get; set; }

    public void eat()
    {

    }
}

Затем в классе Program определили метод Update2:

private void Update2<T>(Action<T> exp)
{

}

Метод Update2 можно вызвать так:

Update2<UserInfo>(u => {
   u.Age = 120;
   u.State = false;
   u.UserName = "what's name";
});

Можно ли узнать обновленные свойства и значение? Или могу ли я использовать выражение, чтобы узнать это?

обновлять

private void Update1<T>(Expression<Action<T>> exp)
{

}

если вы используете метод Update1, вы можете называть его только лайками Update1<UserInfo>(u => u.eat());. Если вы используете

Update1<UserInfo>(u => {
     u.Age = 123;
     u.State = false
});

возникнет ошибка: Ошибка (активная) CS0834. Лямбда-выражение с телом инструкции невозможно преобразовать в дерево выражений.

Вы пытаетесь избежать использования дерева выражений? ИМХО, это наиболее естественный подход.

Sweeper 16.08.2024 09:03

Можете ли вы объяснить немного больше, что вы собираетесь Update2 делать?

Magnus 16.08.2024 09:04

В чем/где именно здесь вопрос? Ваш анонимный объект, переданный в Update2, существует только во время его вызова, до или после него проверять нечего. Ваши намерения мне не ясны.

Kris 16.08.2024 09:07

кто сказал, что вы вообще обновляете какую-либо собственность? Вы также можете сделать Update2<UserInfo>(u => Console.WriteLine("Hello")). Единственный способ — проанализировать выражение, в котором используется Expression<Action<T>> вместо Action<T>.

MakePeaceGreatAgain 16.08.2024 09:18

с точки зрения MakePeaceGreatAgain, этот недавний вопрос может представлять интерес

Ivan Petrov 16.08.2024 09:26

@Sweeper, на самом деле я хочу использовать дерево выражений. и я также определил метод Private void Update1<T>(Expression<Action<T>> exp) { ... }```.

goldii 16.08.2024 09:26

@Магнус, на самом деле я пытаюсь написать функцию обновления sql. я хочу использовать u => { u.Age = 123; ... }

goldii 16.08.2024 09:28

@MakePeaceGreatAgain, @rotabor мне нужно выражение u => { u.age = ... } , а не еще один вызов метода

goldii 16.08.2024 09:31

Это была не моя точка зрения. Дело в том, что внутри вашего Update2-метода вы просто понятия не имеете, какой тип Action был предоставлен, это может быть буквально всё, а не только задание. Опять же: используйте Expression, если хотите получить представление о делегате.

MakePeaceGreatAgain 16.08.2024 09:38

@MakePeaceGreatAgain, да, ты прав.

goldii 16.08.2024 09:39

Разве вы не видели ошибку: дерево выражений не может содержать оператор присваивания?

shingo 16.08.2024 09:41

@shingo, если использовать только Update2, ошибки не будет.

goldii 16.08.2024 09:44

@goldii ты не можешь использовать для этого EF?

Magnus 16.08.2024 09:48

@Магнус, спасибо за предложение. но я хочу написать свой собственный.

goldii 16.08.2024 09:50

Итак, вы пытаетесь написать свой собственный поставщик linq to SQL?

Magnus 16.08.2024 09:52

Предполагаете ли вы, что в аргументе u есть только присвоения свойствам Update2? Может ли вызывающий абонент, например, установить какое-то свойство, а затем вызвать другой метод?

Sweeper 16.08.2024 09:52

@Sweeper, задавай только значение свойства. никакой другой вызов метода

goldii 16.08.2024 09:54

@Магнус. Да, это

goldii 16.08.2024 10:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
19
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Дерево выражений может не содержать оператора присваивания, но вы можете использовать Expression<Func<T>> вместо Action<T>, чтобы прочитать MemberInitExpression:

private void Update1<T>(Expression<Func<T>> exp)
{
    if (exp.Body is MemberInitExpression exp2)
    {
        foreach (var b in exp2.Bindings)
        {
            if (b is MemberAssignment ma)
            {
                // left property
                Console.WriteLine(ma.Member);
                // right expression
                Console.WriteLine(ma.Expression);
            }
        }
    }
}

Update1(() => new UserInfo
{
    Age = 120,
    State = false,
    UserName = "what's name",
});

Поскольку это чтение выражения, оно фактически не выделяет этот объект.

Это умный метод. Если нет лучшего способа, возможно, это единственный способ

goldii 16.08.2024 10:18

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