鉴于以下课程:
class TestClass { public void SetValue(int value) { Value = value; } public int Value { get; set; } }
我可以
TestClass tc = new TestClass(); ActionsetAction = tc.SetValue; setAction.Invoke(12);
这一切都很好.是否可以使用属性而不是方法来做同样的事情?最好是内置于.net的东西.
您可以使用反射创建委托:
ActionvalueSetter = (Action )Delegate.CreateDelegate(typeof(Action ), tc, tc.GetType().GetProperty("Value").GetSetMethod());
或者创建一个设置属性的匿名方法的委托;
ActionvalueSetter = v => tc.Value = v;
编辑:对CreateDelegate()使用了错误的重载,需要使用一个以对象为目标的对象.固定.
有三种方法可以做到这一点; 第一种是使用GetGetMethod()/ GetSetMethod()并使用Delegate.CreateDelegate创建委托.第二个是lambda(反射用途不多!)[即x => x.Foo].第三种是通过Expression(.NET 3.5).
lambda是最简单的;-p
class TestClass { public int Value { get; set; } } static void Main() { FunclambdaGet = x => x.Value; Action lambdaSet = (x, val) => x.Value = val; var prop = typeof(TestClass).GetProperty("Value"); Func reflGet = (Func ) Delegate.CreateDelegate( typeof(Func ), prop.GetGetMethod()); Action reflSet = (Action )Delegate.CreateDelegate( typeof(Action ), prop.GetSetMethod()); }
显示用法:
TestClass foo = new TestClass(); foo.Value = 1; Console.WriteLine("Via property: " + foo.Value); lambdaSet(foo, 2); Console.WriteLine("Via lambda: " + lambdaGet(foo)); reflSet(foo, 3); Console.WriteLine("Via CreateDelegate: " + reflGet(foo));
请注意,如果您希望委托指向特定实例,则可以使用闭包作为lambda,或者接受和实例的CreateDelegate的重载.