代码之家  ›  专栏  ›  技术社区  ›  Robert Höglund

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

  •  13
  • Robert Höglund  · 技术社区  · 16 年前

    考虑到以下类别:

    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 回复  |  直到 16 年前
        1
  •  21
  •   Pop Catalin    16 年前

    可以使用反射创建代理:

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

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

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

    edit:对createDelegate()使用了错误的重载,需要使用接受和对象作为目标的重载。固定的。

        2
  •  12
  •   Marc Gravell    16 年前

    有三种方法可以做到这一点:第一种是使用getgetgetmethod()/getsetmethod()并使用delegate.create delegate创建委托。第二个是lambda(不太适合反射!)[即x=>x.foo]。第三个是via表达式(.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的重载。

        3
  •  3
  •   Kieron    16 年前

    属性实际上是.NET中方法的包装器,因此使用反射,您应该能够获取委托(设置属性和获取属性),然后执行它们…

    System.Reflection.PropertyInfo

    如果有两种方法可用于获取/设置值,则分别为get getgetmethod和getsetmethod。

    所以你可以写:

    var propertyInfo = typeof (TestClass).GetProperty ("Value");
    
    var setMethod = property.GetSetMethod (); // This will return a MethodInfo class.