Search code examples
c#expression

Is it possible to extract properties and values from Action<T>?


First, I defined a class, like:

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

    public void eat()
    {

    }
}

Then, in class Program, defined a method Update2:

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

}

The method Update2 can be called like:

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

Is it possible to know the updated properties and value? Or, can I use an expression to know that?

update

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

}

if using Update1 method, you can only call it likes Update1<UserInfo>(u => u.eat());. If you use

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

there will be an error : Error (active) CS0834 A lambda expression with a statement body cannot be converted to an expression tree


Solution

  • An expression tree may not contain an assignment operator, but you can use Expression<Func<T>> instead of Action<T> to read a 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",
    });
    

    Because this is reading an expression, it will not actually allocate this object.