代表所有方法

时间:2015-06-07 14:43:32

标签: c# delegates

我想实现一个TaskQueue。 我将任务添加到队列中,当我调用Run()时,任务将由一个线程执行。

class Executer
{
    private Queue<Task> TaskQueue;

    private Thread thread;

    public Executer()
    {
        this.TaskQueue = new Queue<QueueNode>();
    }

    public void AddTask(Task task)
    {
        this.TaskQueue.Enqueue(task);
    }

    public void Run()
    {
        this.thread = new Thread(() => ThreadMethod);

        this.thread.Start();
    }
}

ThreadMethod循环遍历Queue并执行Task

但我的问题是我找不到Task的数据类型,因为Task可能就是一切。

假设我只想调用带int参数的方法。然后很容易.. Task可能是这样的:

Action<int> Task = object.AddToTheObjectCounter(5);

但这只是无数人的一个案例。

你能给我一个小费吗?

我也考虑过通过

动态调用方法
object.GetType().GetMethod("AddToTheObjectCounter") // ...

但我认为这不好,因为当我有拼写错误时,代码会编译但会崩溃。

提示: 我发现你可以用一个可变的参数计数来调用代表(看下面的答案):

private void TestMethod()
{
    Delegate function = (Func<int, int, int>)((a, b) => a * b);
    object[] parameters = new object[] {7, 2};
    var result = (int)function.DynamicInvoke(parameters);
}

2 个答案:

答案 0 :(得分:3)

嗯,有Delegate

private Queue<Delegate> TaskQueue;
...

public void AddTask(Delegate task)
{
    this.TaskQueue.Enqueue(task);
}

但是,使用AddTask添加任务时,它不会像以前一样容易。您首先需要转换为已知的委托(Func<>),然后传递参数。

obj.AddTask((Func<...>)nameOfTheMethod);
// obj.AddTask((Func<string[], void>)Console.WriteLine);

当您致电Delegate实例时,您无法使用operator(),因为您不确定该功能实际上是什么。您必须改为使用DynamicInvoke

答案 1 :(得分:1)

您可以使用匿名方法:

void Print(string str) {
    Console.WriteLine("str");
}

var queue = new List<Action> {
    () => Print("Hello"),
    () => Print(" world!"),
    () => {
        Print("Bla bla bla");
        Print("-----------");
    }
};
for each(var task in queue) {
    task();
}

结果将是:

Hello
 world!
Bla bla bla
-----------