Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 扩展方法上的CreateDelegate_C#_Extension Methods - Fatal编程技术网

C# 扩展方法上的CreateDelegate

C# 扩展方法上的CreateDelegate,c#,extension-methods,C#,Extension Methods,我有一个具有IList只读属性的类。我创建了一个简单的扩展方法AddCSV,将多个项目添加到该列表中。我想创建一个动作委托,通过扩展方法填充列表。到目前为止,我已经 private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName) { var list = typeof(TL

我有一个具有IList只读属性的类。我创建了一个简单的扩展方法AddCSV,将多个项目添加到该列表中。我想创建一个动作委托,通过扩展方法填充列表。到目前为止,我已经

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。你是对的,我把它复杂化了!你的代码样本成功了。