这个问题对我来说有点复杂,我不是C#guru。
基本上我有一些我想要处理的任务的队列。我希望能够将各种方法推送到该队列,它们将执行不同的操作,但所有方法都将一个字符串作为参数。问题是:如何通过代表的使用实现这一目标?我不知道怎么做,所以编译器不会抛出任何错误。
或多或少地说明我想要做的事情的代码:
delegate void Del(string);
Queue<Del> Q = new Queue<Del>();
public DT()
{
string foo = "bar";
Q.Enqueue((foo) =>
{
//do some stuff
});
}
//somewhere else I constantly check the queue and run the tasks
这种设计可能看起来很奇怪,但在这方面,我确定我在做什么。
因此,这给出了编译器错误,即无法声明局部变量foo。当然我不想声明它,我想将它传递给正在推送队列的函数。我该怎么办?
我希望你理解我的问题。谢谢。
答案 0 :(得分:3)
只使用不同的lambda参数名称(目前它与本地foo
变量声明冲突):
Q.Enqueue(f => {
//do some stuff
});
然后你可以从队列中获取一个传递参数委托给它:
Q.Dequeue()(foo);
如果你想捕获foo
变量的值,那么只需在做一些东西部分中使用它。在这种情况下,您可能希望委托具有签名,该签名不接受任何输入参数:
Queue<Action> actions = new Queue<Action>();
string foo = "bar";
actions.Enqueue(() => Console.WriteLine(foo));
actions.Dequeue()();
顺便说一句:您不需要创建这些代表 - 使用现有的Action<T>
或Action
代表。
答案 1 :(得分:2)
委托类型形成最终呼叫的签名。由于您已经说过在对其进行排队时提供了字符串,因此该调用的签名是
delegate void Del();
Queue<Del> Q = new Queue<Del>();
现在加入队列:
public DT()
{
string foo = "bar";
Q.Enqueue(() =>
{
//do some stuff using foo
});
}
foo
的值在lambda中的范围内,并且在它被入队之前将被捕获到委托中。这称为闭包。
请注意,您可以使用预定义的委托类型System.Action
,而不是创建自己的委托。