可以通过C#中的数组调用方法吗?

时间:2012-07-11 17:06:50

标签: c# arrays methods delegates

我有一个程序需要运行不同的方法,具体取决于我想要它与之交谈,我想知道是否有一种方法可以在数组中存储某种方法指针或类似的东西。所以我想要一个数组,其中每个元素都是这样的:

[Boolean:Do_this?] [Function_pointer] [传递给函数的数据]

基本上,我可以将它放入for循环中,而不是单独调用每个函数。另一个代码块将填充是否运行此函数的布尔值,然后我的for循环将通过并使用适当的数据运行该函数,如果布尔值为真。

我知道委托类似于函数指针,但如果这就是答案,我不完全确定如何构建我想构建的东西。

这在C#中是否可行?

5 个答案:

答案 0 :(得分:3)

当然,这样做,你需要所有方法都有相同的签名:

假设您有两种方法:

public int Moop(string s){ return 1; }
public int Moop2(string s){ return 2; }

你可以这样做:

var funcs = new Func<string, int>[]{ Moop, Moop2 };

致电:

var val = funcs[0]("hello");

答案 1 :(得分:2)

您可以声明要在委托中保留的特定对象类型,该标志指示是执行该操作还是现在操作以及数据。请注意,您所描述的内容与 events 非常相似,因为它们也是由回调和一些事件数据定义的。

骨架模型看起来像这样,假设您要调用的所有方法都具有相同的签名(如果您需要通过反射使用各种签名,则可以解决这个问题):

// This reflects the signature of the methods you want to call
delegate void theFunction(ActionData data);

class ActionData
{
    // put whatever data you would want to pass
    // to the functions in this wrapper
}

class Action
{
    public Action(theFunction action, ActionData data, bool doIt)
    {
        this.action = action;
        this.data = data;
        this.doIt = doIt;
    }

    public bool doIt
    {
        get;
        set;
    }

    public ActionData data
    {
        get;
        set;
    }

    public theFunction action
    {
        get;
        set;
    }

    public void run()
    {
        if (doIt)
            action(data);
    }
}

常规用例看起来像这样:

class Program
{
    static void someMethod(ActionData data)
    {
        Console.WriteLine("SUP");
    }

    static void Main(string[] args)
    {
        Action[] actions = new Action[] {
            new Action(Program.someMethod, new ActionData(), true)
        };

        foreach(Action a in actions) 
            a.run();
    }
}

答案 2 :(得分:1)

是的,你可以。

如果您的所有功能共享相同的签名,您可能希望将代理存储在您的集合中,否则我会选择System.Reflection.MethodInfo,您可以稍后通过调用Invoke方法使用该Invoke。参数将存储为对象数组 - 这就是Reflection.Emit所期望的。

如果使用反射太慢,可以使用{{1}}在运行时生成动态方法。

答案 3 :(得分:1)

我只想创建一个List<Action>。 Action是一个不带参数且没有返回结果的委托。您可以使用currying和lambdas,以便实际操作可以调用具有参数的方法。在您实际上不想运行它的情况下,只是不要首先将它添加到列表中(或者添加一个我不想做的动作)。

要添加项目,它可能类似于:

list.Add(() => someobject.someMethod(firstArgument, secondArgument));
list.Add(() => anotherObject.anotherMethod(oneArgument));

然后您可以在需要时运行所有操作:

foreach(Action action in list)
{
  action();
}

答案 4 :(得分:0)

这正是您将使用委托的内容。代表或多或少是类型检查函数指针。您可以创建一些委托并将它们放入数组中。

Func<int, int> [] funcs = new Func<int,int>[] { x => 2 * x, x => x * x };
foreach(var fn in funcs) 
{
    Console.WriteLine(fn(3));
    Console.WriteLine(fn(8));
}