委托方法 - 如果我不知道什么类型或多少参数,如何调用和传递参数

时间:2012-05-11 15:26:23

标签: c# delegates

假设我有代表......

public delegate void MyAction(params object[] args);

一个带有使用该delagate的子类的类......

public class MyClass {
    public List<MySubClass> mySubClasses;
}

public class MySubClass {
    public string myString;
    public MyAction myDelegateMethod;
}

我希望能够在运行时将任何方法传递给myDelegateMethod,它可以接受任意数量的不同类型的参数。像这样......

MyClass myClass = new MyClass(){
    mySubClasses = {
        new MySubClass {
            myString = "help",
            myDelegateMethod = Method1 
        },
        new MySubClass {
            myString = "me",
            myDelegateMethod = Method2 
        }
    }   
};

public string Method1(object myObject) { ... }
public string Method2(string value, Guid id) { ... }

如何在运行时调用这些方法中的每个方法传递适当的参数?

myClass.mySubClasses.ForEach(x => {
    x.myDelegateMethod; // <-- this is where I'm stumped. how do i pass arguments here?
});

这可能吗?也许我有一些错误的做法?

2 个答案:

答案 0 :(得分:2)

这是不可能的,因为Method1Method2不是void <Name> (params object)个代表。它们不是同一类型(甚至可以与兼容类型的方差转换),考虑到它们返回不同的值并执行不同的参数。

如果你想执行一个任意的方法,那么我能想到的唯一方法就是将一个包装的方法执行作为一个动作:

var sample = new List<MyClass>
{
    new MyClass
    {
        SomeProperty = "Help",
        Method = new Action(() =>
          {
              ExecuteMethod1("Hello", "World");
          })
    },
    new MyClass
    {
        SomeProperty = "Me",
        Method = new Action(() =>
          {
              ExecuteMethod2(1, 2, 3, 4);
          })
    },
};

然后你就可以这样执行:

myClass.ForEach(x => x.Method());

在这种情况下,您需要在Method中明确地包装您想要执行的任何操作(使用创建时已知的参数)。

答案 1 :(得分:0)

首先,Method2不能用作您的委托。这样做也不是一个好习惯。你可以尝试用反射来做,但对于那些阅读你的代码的人来说,这是难以理解的。 所以,我认为,您应该使用所有方法,例如委托类型,但是在方法内部转换为需要类型,如下所示:

public void Method1(params object[] pars)
{
    string value = (string)pars[0];
    Guid id = (Guid)pars[1];
}

或使用之前回答中的某种闭包。