Простые делегаты (делегаты) и делегаты многоадресной передачи
Я просмотрел много статей, но до сих пор неясно, в чем разница между обычными делегатами, которые мы обычно создаем, и делегатами многоадресной рассылки.
public delegate void MyMethodHandler(object sender);
MyMethodHandler handler = new MyMethodHandler(Method1);
handler += Method2;
handler(someObject);
Вышеупомянутый делегат MyMethodHandler вызовет эти два метода.
Теперь, куда входят делегаты многоадресной передачи. Я читал, что они могут вызывать несколько методов, но я боюсь, что мое основное понимание делегатов неверно.
Ответы
Ответ 1
Эта статья объясняет это довольно хорошо:
delegate void Del(string s);
class TestClass
{
static void Hello(string s)
{
System.Console.WriteLine(" Hello, {0}!", s);
}
static void Goodbye(string s)
{
System.Console.WriteLine(" Goodbye, {0}!", s);
}
static void Main()
{
Del a, b, c, d;
// Create the delegate object a that references
// the method Hello:
a = Hello;
// Create the delegate object b that references
// the method Goodbye:
b = Goodbye;
// The two delegates, a and b, are composed to form c:
c = a + b;
// Remove a from the composed delegate, leaving d,
// which calls only the method Goodbye:
d = c - a;
System.Console.WriteLine("Invoking delegate a:");
a("A");
System.Console.WriteLine("Invoking delegate b:");
b("B");
System.Console.WriteLine("Invoking delegate c:");
c("C");
System.Console.WriteLine("Invoking delegate d:");
d("D");
}
}
/* Output:
Invoking delegate a:
Hello, A!
Invoking delegate b:
Goodbye, B!
Invoking delegate c:
Hello, C!
Goodbye, C!
Invoking delegate d:
Goodbye, D!
*/
Ответ 2
В спецификации С# указано, что все типы делегатов должны быть конвертированы в System.Delegate
. Фактически, реализация реализует это, что все типы делегатов выводятся из System.MulticastDelegate
, который, в свою очередь, происходит от System.Delegate
.
Это ясно? Я не уверен, что ответил на ваш вопрос.
Ответ 3
"Все экземпляры делегатов имеют возможность многоадресной рассылки". - http://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx
"В С# все типы делегатов поддерживают многоадресную рассылку" - http://msdn.microsoft.com/en-us/library/orm-9780596516109-03-09.aspx
Ответ 4
Извините за добавление к кому-то другому ответа, но я подумал, что делегаты вызываются в том порядке, в котором они добавлены.
раздел "Многоадресные делегаты"
http://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx
Ответ 5
Чтобы уточнить бит: все делегаты являются экземплярами класса MulticastDelegate
, независимо от того, имеют ли они один или несколько целевых методов. В принципе нет никакой разницы между делегатом с одной или несколькими целями, хотя среда выполнения немного оптимизирована для общего случая с одной целью. (Делегат с 0 целями невозможен, хотя он один или несколько.)
Когда вы создаете делегат, например new MyMethodHandler(Method1)
, вы создаете делегат с одной целью (метод Method1
).
Делегаты с несколькими целями создаются путем объединения двух существующих делегатов. Получаемый делегат будет иметь сумму целевых показателей. Делегаты могут быть объединены явно с помощью Delegate.Combine()
, но также неявно с помощью оператора +=
для существующего делегата, как в вашем примере.
Вызов делегата в свою очередь вызывает каждую цель в делегате. Поэтому в вашем примере handler(someObject);
вызовет два метода (Method1
и Method2
), так как вы создали делегат с этими двумя целями.