Creating a property setter delegate

前端 未结 4 571
误落风尘
误落风尘 2020-11-30 22:23

I have created methods for converting a property lambda to a delegate:

public static Delegate MakeGetter(Expression> propertyLam         


        
4条回答
  •  南方客
    南方客 (楼主)
    2020-11-30 23:02

    The Expression API supports this in .NET 4.0, but sadly the C# compiler doesn't add any extra candy to support. But the good news is that you can trivially take a "get" expression (which the C# compiler can write) and re-write it as a "set" expression.

    And even better; if you don't have .NET 4.0, there are still at least two other ways of performing a "set" via an expression written as a "get".

    Here they all are, for info:

    using System;
    using System.Linq.Expressions;
    using System.Reflection;
    class Foo {
        public string Bar { get; set; }
        static void Main() {
            // take a "get" from C#
            Expression> get = foo => foo.Bar;
    
            // re-write in .NET 4.0 as a "set"
            var member = (MemberExpression)get.Body;
            var param = Expression.Parameter(typeof(string), "value");
            var set = Expression.Lambda>(
                Expression.Assign(member, param), get.Parameters[0], param);
    
            // compile it
            var action = set.Compile();
            var inst = new Foo();
            action(inst, "abc");
            Console.WriteLine(inst.Bar); // show it working
    
            //==== reflection
            MethodInfo setMethod = ((PropertyInfo)member.Member).GetSetMethod();
            setMethod.Invoke(inst, new object[] { "def" });
            Console.WriteLine(inst.Bar); // show it working
    
            //==== Delegate.CreateDelegate
            action = (Action)
                Delegate.CreateDelegate(typeof(Action), setMethod);
            action(inst, "ghi");
            Console.WriteLine(inst.Bar); // show it working
        }
    }
    

提交回复
热议问题