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