委托Generic Property.GetSetMethod

时间:2011-11-10 23:01:35

标签: c# generics delegates

我正在尝试创建一个委托来设置泛型的属性值,但是当我尝试执行以下代码时出现错误:Error binding to target method

Action<T, object> setValue = (Action<T, object>) Delegate.CreateDelegate(
    typeof(Action<T, object>), null, property.GetSetMethod());

这甚至可能吗?

3 个答案:

答案 0 :(得分:3)

是的,有可能,你只是想创建一个错误类型的委托。属性的set方法只接受一个参数,即您要设置的值。此外,由于它是一个实例方法,您必须在CreateDelegate调用中传递您希望它绑定到的目标对象。

示例:

  var setValue = (Action<T>)Delegate.CreateDelegate( typeof( Action<T> ), target, property.GetSetMethod() );

答案 1 :(得分:1)

我想你想要这个:

Action<T, object> setValue = (t, o) => property.GetSetMethod().Invoke(t, new object[] { o });

Action<T, object> setValue = (t, o) => property.SetValue(t, o, null);

修改

为了说明这个答案假定的较差的表现与接受的答案相比,假设这个方法:

void SetAnObjectPropertyOnALotOfObjects<T>(IEnumerable<T> objs)
{
    //Create a delegate and assign a reference to that delegate to the setValue variable
    Action<T, object> setValue = GetSetter();

    foreach (var o in objs)
    {
        //invoke the delegate referred to by the setValue variable (that is, "invoke its referent"
        setValue.Invoke(o, new object());
    }
}

MerickOWA的答案使用GetSetter方法中的反射,因此我们假设GetSetter方法在他的方法中需要更多时间来执行。每次调用setValue.Invoke时,此答案都会使用反射,因此我们假设在此答案中需要更多时间来执行。如果我们假设序列中的项目数量很大,那么MerickOWA的答案应该需要更少的时间来执行。

例如,假设MerickOWA的GetSetter方法比我的执行需要X毫秒多,而我的setValue委托比他的需要花费Y毫秒。如果序列中有N个项目,那么我的解决方案应该比他的(N * Y - X)毫秒慢。

答案 2 :(得分:1)

这取决于。在我的回答中,我假设有两件事:

  1. 您的类型“T”是您班级的类型(我现在将其称为TClass)
  2. “对象”类型是您的属性的类型(我现在将其称为TProperty)
  3. 因为您的属性是非静态的,所以有两种可能性:

    1. 附加目标(实例)的“普通”委托。
    2. 一个“开放”委托,其中需要一个目标作为委托的第一个输入参数。
    3. 创建此类“普通”委托的函数创建如下:

      static public Action<TClass, TProperty> CreateSetPropertyDelegate<TClass, TProperty>(this PropertyInfo propertyInfo)
      {
          return (Action<TClass, TProperty>)Delegate.CreateDelegate(typeof(Action<TClass, TProperty>), propertyInfo.GetSetMethod());
      }
      

      并且在使用中(假设属性类型为int类型):

      Action<int> setter = typeof(MyClass).GetProperty("MyProperty").CreateSetPropertyDelegate<MyClass, int>(myInsance);
      setter(myPropertyValue);
      

      创建开放代表的功能:

      static public Action<TClass, TProperty> CreateSetPropertyDelegate<TClass, TProperty>(this PropertyInfo propertyInfo)
      {
          return (Action<TClass, TProperty>)Delegate.CreateDelegate(typeof(Action<TClass, TProperty>), propertyInfo.GetSetMethod());
      }
      

      并在使用中:

      Action<MyClass, int> setter = typeof(MyClass).GetProperty("MyProperty").CreateSetPropertyDelegate<MyClass, int>();
      setter(myInsance, myPropertyValue);