C# 中是否有可用于属性的委托?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/289980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a delegate available for properties in C#?
提问by Robert H?glund
Given the following class:
鉴于以下类:
class TestClass {
public void SetValue(int value) { Value = value; }
public int Value { get; set; }
}
I can do
我可以
TestClass tc = new TestClass();
Action<int> setAction = tc.SetValue;
setAction.Invoke(12);
which is all good. Is it possible to do the same thing using the property instead of the method? Preferably with something built in to .net.
这一切都很好。是否可以使用属性而不是方法来做同样的事情?最好是 .net 内置的东西。
采纳答案by Pop Catalin
You could create the delegate using reflection :
您可以使用反射创建委托:
Action<int> valueSetter = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), tc, tc.GetType().GetProperty("Value").GetSetMethod());
or create a delegate to an anonymous method which sets the property;
或创建一个匿名方法的委托来设置属性;
Action<int> valueSetter = v => tc.Value = v;
Edit: used wrong overload for CreateDelegate(), need to use the one that takes and object as target. Fixed.
编辑:为 CreateDelegate() 使用了错误的重载,需要使用以和对象为目标的重载。固定的。
回答by Kieron
Properties are really wrappers around methods in .Net, so using reflection you should be able to get the delegate (set_PROPERTY and get_PROPERTY) and then execute them...
属性实际上是 .Net 中方法的包装器,因此使用反射您应该能够获取委托(set_PROPERTY 和 get_PROPERTY),然后执行它们...
See System.Reflection.PropertyInfo
请参阅System.Reflection.PropertyInfo
If has two methods which you can use to get/ set the value - GetGetMethod and GetSetMethod.
如果有两种方法可用于获取/设置值 - GetGetMethod 和 GetSetMethod。
So you could write:
所以你可以写:
var propertyInfo = typeof (TestClass).GetProperty ("Value");
var setMethod = property.GetSetMethod (); // This will return a MethodInfo class.
回答by Marc Gravell
There are three ways of doing this; the first is to use GetGetMethod()/GetSetMethod() and create a delegate with Delegate.CreateDelegate. The second is a lambda (not much use for reflection!) [i.e. x=>x.Foo]. The third is via Expression (.NET 3.5).
有三种方法可以做到这一点;第一种是使用 GetGetMethod()/GetSetMethod() 并使用 Delegate.CreateDelegate 创建委托。第二个是 lambda(反射用处不大!)[即 x=>x.Foo]。第三个是通过 Expression (.NET 3.5)。
The lambda is the easiest ;-p
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());
}
To show usage:
显示用法:
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));
Note that if you want the delegate pointing to the specific instance, you can use closures for the lambda, or the overload of CreateDelegate that accepts and instance.
请注意,如果您希望委托指向特定实例,您可以使用 lambda 的闭包,或接受和实例的 CreateDelegate 的重载。