C# 扩展方法上的CreateDelegate
我有一个具有IList只读属性的类。我创建了一个简单的扩展方法AddCSV,将多个项目添加到该列表中。我想创建一个动作委托,通过扩展方法填充列表。到目前为止,我已经C# 扩展方法上的CreateDelegate,c#,extension-methods,C#,Extension Methods,我有一个具有IList只读属性的类。我创建了一个简单的扩展方法AddCSV,将多个项目添加到该列表中。我想创建一个动作委托,通过扩展方法填充列表。到目前为止,我已经 private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName) { var list = typeof(TL
private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
{
var list = typeof(TListPropertyContainer).GetProperty(listName);
var method = typeof(Extensions).GetMethod("AddCSV");
return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}
私有操作CreateListPropertySetter(字符串listName)
{
var list=typeof(TListPropertyContainer).GetProperty(listName);
var method=typeof(Extensions).GetMethod(“AddCSV”);
return(Action)Delegate.CreateDelegate(typeof(Action)、list、method);
}
但很明显,这是行不通的
我知道还有其他选择。例如
a) 我可以将列表继承到我自己的customer类中,并在其中添加AddCSV
b) 我可以使items属性读/写,并在类中设置一个完全填充的列表
如果有人能纠正我,我将不胜感激
许多thx
Simon您试图将
列表
用作代理的目标-但是列表
的类型为属性信息
,这听起来似乎不是您所期望的。假设您想要获取属性的值,然后对该值调用方法,那么您还需要传入包含该属性的对象,这样才能获得实际的列表。(或者,可能是“这个”-你还没有说清楚。)无论哪种方式,你都可以得到列表本身并将其作为目标。例如:
private Action<TListPropertyContainer, TDataValue>
CreateListPropertySetter<TListPropertyContainer, TDataValue>
(string listName, object target)
{
var listProperty = typeof(TListPropertyContainer).GetProperty(listName);
object list = listProperty.GetValue(target, null);
var method = typeof(Extensions).GetMethod("AddCSV");
return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(
typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}
私人行动
CreateListPropertySetter
(字符串listName,对象目标)
{
var listProperty=typeof(TListPropertyContainer).GetProperty(listName);
对象列表=listProperty.GetValue(目标,空);
var method=typeof(Extensions).GetMethod(“AddCSV”);
返回(操作)委托。CreateDelegate(
类型(动作)、列表、方法);
}
如果这没有帮助,请用一个简短但完整的控制台应用程序来演示问题,编辑您的问题。现在有太多的未知数对您毫无帮助。您试图使用
list
作为代理的目标-但是list
属于PropertyInfo
类型,这听起来好像不是您所期望的。假设您想要获取属性的值,然后对该值调用方法,那么您还需要传入包含该属性的对象,这样才能获得实际的列表。(或者,可能是“这个”-你还没有说清楚。)无论哪种方式,你都可以得到列表本身并将其作为目标。例如:
private Action<TListPropertyContainer, TDataValue>
CreateListPropertySetter<TListPropertyContainer, TDataValue>
(string listName, object target)
{
var listProperty = typeof(TListPropertyContainer).GetProperty(listName);
object list = listProperty.GetValue(target, null);
var method = typeof(Extensions).GetMethod("AddCSV");
return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(
typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}
私人行动
CreateListPropertySetter
(字符串listName,对象目标)
{
var listProperty=typeof(TListPropertyContainer).GetProperty(listName);
对象列表=listProperty.GetValue(目标,空);
var method=typeof(Extensions).GetMethod(“AddCSV”);
返回(操作)委托。CreateDelegate(
类型(动作)、列表、方法);
}
如果这没有帮助,请用一个简短但完整的控制台应用程序来演示问题,编辑您的问题。现在有太多的未知数肯定对你有帮助。有两个主要问题
属性info
而不是列表上调用该方法。要获取属性的值,需要调用GetValue()
GetMethod()
的调用未指定绑定标志。我怀疑使用GetMethod(“AddCSV”,BindingFlags.Public | BindingFlags.Static)
可能会更好 private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
{
var propertyInfo = typeof(TListPropertyContainer).GetProperty(listName);
return (container,value) => {
var list = (IList<TDataValue>)propertyInfo.GetValue(container,null);
list.AddCSV(list);
};
}
私有操作CreateListPropertySetter(字符串listName)
{
var propertyInfo=typeof(TListPropertyContainer).GetProperty(listName);
返回(容器、值)=>{
var list=(IList)propertyInfo.GetValue(容器,null);
list.AddCSV(list);
};
}
如果我对扩展方法的签名或属性的类型做出了错误的假设,您仍然可以使用
Delegate.CreateDelegate()
,但是要考虑有关PropertyInfo
和BindingFlags
的注释,主要有两个问题
属性info
而不是列表上调用该方法。要获取属性的值,需要调用GetValue()
GetMethod()
的调用未指定绑定标志。我怀疑使用GetMethod(“AddCSV”,BindingFlags.Public | BindingFlags.Static)
可能会更好 private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
{
var propertyInfo = typeof(TListPropertyContainer).GetProperty(listName);
return (container,value) => {
var list = (IList<TDataValue>)propertyInfo.GetValue(container,null);
list.AddCSV(list);
};
}
私有操作CreateListPropertySetter(字符串listName)
{
var propertyInfo=typeof(TListPropertyContainer).GetProperty(listName);
返回(容器、值)=>{
var list=(IList)propertyInfo.GetValue(容器,null);
list.AddCSV(list);
};
}
如果我对扩展方法的签名或属性类型做出了错误的假设,您仍然可以使用
Delegate.CreateDelegate()
,但要考虑有关PropertyInfo
和BindingFlags
的注释。我从你所说的话中看出了我的错误。我来做个样品。这里的问题是,我将在调用委托时传递实例,而不是在创建委托时传递实例。我从你所说的话中看出了我的错误。我来做个样品。这里的问题是,我将在调用委托时传递实例,而不是在创建委托时传递实例。你是对的,我把它复杂化了!你的代码样本成功了。很多thx。你是对的,我把它复杂化了!你的代码样本成功了。