C# 泛型属性的委托。GetSetMethod
我正在尝试创建一个委托来设置泛型的属性值,但在尝试执行以下代码时遇到错误:C# 泛型属性的委托。GetSetMethod,c#,generics,delegates,C#,Generics,Delegates,我正在尝试创建一个委托来设置泛型的属性值,但在尝试执行以下代码时遇到错误:错误绑定到目标方法: Action<T, object> setValue = (Action<T, object>) Delegate.CreateDelegate( typeof(Action<T, object>), null, property.GetSetMethod()); Action setValue=(Action)Delegate.CreateDelegat
错误绑定到目标方法
:
Action<T, object> setValue = (Action<T, object>) Delegate.CreateDelegate(
typeof(Action<T, object>), null, property.GetSetMethod());
Action setValue=(Action)Delegate.CreateDelegate(
typeof(Action),null,property.GetSetMethod());
这可能吗?我想你想要这个:
Action<T, object> setValue = (t, o) => property.GetSetMethod().Invoke(t, new object[] { o });
Action setValue=(t,o)=>property.GetSetMethod().Invoke(t,新对象[]{o});
或
Action 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());
}
}
void SetAnObjectPropertyOnALotOfObjects(IEnumerable objs)
{
//创建一个委托,并将对该委托的引用指定给setValue变量
Action setValue=GetSetter();
foreach(objs中的var o)
{
//调用setValue变量引用的委托(即“调用其引用对象”
调用(o,新对象());
}
}
MerickOWA的答案在GetSetter
方法中使用反射,因此我们假设在他的方法中GetSetter
方法需要更多的时间来执行。这个答案在每次调用setValue.Invoke
时都使用反射,因此我们假设在这个答案中执行需要更多的时间。如果我们假设由于顺序很大,梅里科娃的回答应该需要较少的时间来执行
例如,假设MerickOWA的GetSetter方法比我的方法多执行X毫秒,而我的setValue委托比他的方法多执行Y毫秒。如果序列中有N个项,那么我的解决方案应该比他的慢(N*Y-X)毫秒。有可能,您只是试图创建错误类型的委托。属性的set方法只接受一个参数,即您要设置的值。此外,由于它是一个实例方法,您必须在CreateDelegate调用中传递要将其绑定到的目标对象 例如:
var setValue = (Action<T>)Delegate.CreateDelegate( typeof( Action<T> ), target, property.GetSetMethod() );
var setValue=(Action)Delegate.CreateDelegate(typeof(Action)、target、property.GetSetMethod());
视情况而定。在我的回答中,我假设有两件事:
static public Action<TClass, TProperty> CreateSetPropertyDelegate<TClass, TProperty>(this PropertyInfo propertyInfo)
{
return (Action<TClass, TProperty>)Delegate.CreateDelegate(typeof(Action<TClass, TProperty>), propertyInfo.GetSetMethod());
}
静态公共操作CreateSetPropertyLegate(此PropertyInfo PropertyInfo)
{
return(Action)Delegate.CreateDelegate(typeof(Action),propertyInfo.GetSetMethod());
}
和正在使用中(假设属性类型为int类型):
Action setter=typeof(MyClass).GetProperty(“MyProperty”).CreateSetPropertyDelegate(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());
}
静态公共操作CreateSetPropertyLegate(此PropertyInfo PropertyInfo)
{
return(Action)Delegate.CreateDelegate(typeof(Action),propertyInfo.GetSetMethod());
}
在使用中:
Action<MyClass, int> setter = typeof(MyClass).GetProperty("MyProperty").CreateSetPropertyDelegate<MyClass, int>();
setter(myInsance, myPropertyValue);
Action setter=typeof(MyClass).GetProperty(“MyProperty”).CreateSetPropertyDelegate();
setter(myInsance,myPropertyValue);
你的属性是静态属性吗?如果不是,那么你不能传递null。不是,很抱歉我错过了那一部分,但是即使我传递类的实例,它也不能正常工作,我仍然会得到相同的例外情况。每次都使用PropertyInfo设置值,这比CreateDelegate返回的要慢得多。你能告诉我吗告诉我为什么这个方法会慢一些?在我的测试中,lambda的执行时间只有create delegate的一半。@nawfal因为使用这种技术,setValue
是对一个委托的引用,该委托使用反射来获取另一个委托,并用它来设置属性值。每次调用setValue
的referent时,您都在使用反射API。接受答案中的方法使用反射来创建直接设置属性的委托,因此在分配setValue
时只使用了一次反射API;setValue
的调用不使用反射。@phoog但是为什么我用你的答案而不是MerickOWA的答案来提高性能呢?Or我应该把它作为一个单独的问题吗?@nawfal我在我的回答中添加了一个性能讨论,部分是为了澄清“分配setValue变量”和“调用其引用对象”之间的区别。
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);