C#中是否有可用于属性的委托?

时间:2008-11-14 12:50:57

标签: c# .net

鉴于以下课程:

class TestClass {
  public void SetValue(int value) { Value = value; }
  public int Value { get; set; }
}

我能做到

TestClass tc = new TestClass();
Action<int> setAction = tc.SetValue;
setAction.Invoke(12);

这一切都很好。是否可以使用属性而不是方法来做同样的事情?最好是内置于.net的东西。

3 个答案:

答案 0 :(得分:21)

您可以使用反射创建委托:

Action<int> valueSetter = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), tc, tc.GetType().GetProperty("Value").GetSetMethod());

或创建一个设置属性的匿名方法的委托;

Action<int> valueSetter = v => tc.Value = v;

编辑:对CreateDelegate()使用了错误的重载,需要使用带有对象作为目标的对象。固定的。

答案 1 :(得分:12)

有三种方法可以做到这一点;第一种是使用GetGetMethod()/ GetSetMethod()并使用Delegate.CreateDelegate创建委托。第二个是lambda(反射用途不多!)[即X =&GT; 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());
    }

显示用法:

        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的重载。

答案 2 :(得分:3)

属性实际上是.Net中方法的包装器,所以使用反射你应该能够获得委托(set_PROPERTY和get_PROPERTY),然后执行它们......

请参阅System.Reflection.PropertyInfo

如果有两种方法可用于获取/设置值 - GetGetMethod和GetSetMethod。

所以你可以写:

var propertyInfo = typeof (TestClass).GetProperty ("Value");

var setMethod = property.GetSetMethod (); // This will return a MethodInfo class.