Вот буквальный пример того, что вы описываете:
class Program
{
delegate void SomeTimeLaterDelegate(int myValue);
delegate void SayHelloDelegate(string name);
static event SomeTimeLaterDelegate SomeTimeLaterEvent;
static event SayHelloDelegate SayHelloLaterEvent;
static void Main(string[] args)
{
SomeTimeLaterEvent += new SomeTimeLaterDelegate(AnswerAnotherDay);
SayHelloLaterEvent += new SayHelloDelegate(SayHello);
var eventsToRaise = new Queue<Action>();
eventsToRaise.Enqueue(() => SomeTimeLaterEvent.Invoke(100));
eventsToRaise.Enqueue(() => SayHelloLaterEvent.Invoke("Bob"));
eventsToRaise.Enqueue(() => SomeTimeLaterEvent.Invoke(200));
eventsToRaise.Enqueue(() => SayHelloLaterEvent.Invoke("John"));
while (eventsToRaise.Any())
{
var eventToRaise = eventsToRaise.Dequeue();
eventToRaise();
//or eventToRaise.Invoke();
}
Console.ReadLine();
}
static void AnswerAnotherDay(int howManyDays)
{
Console.WriteLine($"I did this {howManyDays}, later. Hurray for procrastination!");
}
static void SayHello(string name)
{
Console.WriteLine($"Hello, {name}");
}
}
Вместо Queue<Delegate>
это Queue<Action>
.Action
представляет вызов метода без передачи каких-либо параметров или получения возвращаемого значения.
Это может показаться нелогичным, поскольку вы передаете параметры.Но вы не передаете параметры в действия.Вы передаете параметры из тела действий.
Это может или не может помочь:
Когда мы объявляем
Action someAction = () => AnswerAnotherDay(5);
Это похоже на объявление метода, которыйвыглядит так:
void MyMethod()
{
AnswerAnotherDay(5);
}
Метод вызывает другой метод и передает аргумент.Но MyMethod
сам по себе не получает никаких аргументов.Когда мы объявляем встроенный метод таким образом, у него нет имени, поэтому он также называется анонимным методом.
Мы также можем объявить действие, которое принимает аргумент, например так:
Action<string> action = (s) => SayHelloLater(s);
action("Bob");
Причина, по которой я продемонстрировал использование Action
без параметров, заключается в том, что вы сказали, что очередь может содержать события разных типов с разными параметрами.
Если бы я собирался вызывать один и тот же метод снова и снова с разными аргументами, то, вероятно, было бы более разумно поместить аргументы в очередь.Затем каждый раз, когда мы вынимаем аргументы из очереди, мы можем вызвать событие со следующими аргументами.
Вот возможное упрощение: возможно, вы думаете о сценарии, в котором вам нужно вызывать события, но в этом примеремы можем сделать то же самое без событий, и это немного проще.
Вместо определения делегатов и событий, добавления определенных методов в качестве обработчиков событий, а затем создания действий, которые вызывают события, мы можем просто создатьдействия, которые вызывают методы.
class Program
{
static void Main(string[] args)
{
var eventsToRaise = new Queue<Action>();
eventsToRaise.Enqueue(() => AnswerAnotherDay(100));
eventsToRaise.Enqueue(() => SayHello("Bob"));
eventsToRaise.Enqueue(() => AnswerAnotherDay(200));
eventsToRaise.Enqueue(() => SayHello("John"));
while (eventsToRaise.Any())
{
var eventToRaise = eventsToRaise.Dequeue();
eventToRaise();
//or eventToRaise.Invoke();
}
Console.ReadLine();
}
static void AnswerAnotherDay(int howManyDays)
{
Console.WriteLine($"I did this {howManyDays}, later. Hurray for procrastination!");
}
static void SayHello(string name)
{
Console.WriteLine($"Hello, {name}");
}
}