Делегат многоадресной рассылки C #

Изучаю насчет делегатов. Как я читал. Я узнал, что добавление более одной функции в делегат называется многоадресным делегатом. На основе этого я написал программу. Вот две функции (AddNumbers и MultiplyNumbers), которые я добавил в MyDelegate. Является ли приведенная ниже программа примером многоадресного делегата?

public partial class MainPage : PhoneApplicationPage
{
    public delegate void MyDelegate(int a, int b);
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        MyDelegate myDel = new MyDelegate(AddNumbers);
        myDel += new MyDelegate(MultiplyNumbers);
        myDel(10, 20);
    }

    public void AddNumbers(int x, int y)
    {
        int sum = x + y;
        MessageBox.Show(sum.ToString());
    }

    public void MultiplyNumbers(int x, int y)
    {
        int mul = x * y;
        MessageBox.Show(mul.ToString());
    }

}

person Arun    schedule 22.02.2013    source источник
comment
Этот вопрос лучше подходит для проверки кода.   -  person Davin Tryon    schedule 22.02.2013
comment


Ответы (3)


Да, это пример делегата многоадресной рассылки. Обратите внимание, что вместо

new MyDelegate(AddNumbers)

вы обычно можете сказать просто

AddNumbers

потому что существует так называемое преобразование группы методов, которое создаст для вас экземпляр делегата.

Также следует отметить, что ваше объявление public delegate void MyDelegate(int a, int b); не должно находиться внутри другого типа (здесь, внутри класса MainPage). Это может быть прямой член пространства имен (поскольку это тип). Но, конечно, вполне допустимо «вложить» его в класс, как это делаете вы, по причинам, аналогичным причинам, по которым вы создаете вложенные классы.

person Jeppe Stig Nielsen    schedule 22.02.2013
comment
преобразование группы методов происходит только тогда, когда мы назначили метод, который перегружен, и по крайней мере одна перегрузка соответствует делегату. В этом случае преобразование группы методов не происходит. - person Freeman; 22.02.2013
comment
@Freeman Я предполагал, что он изменил свой код на этот: MyDelegate myDel = AddNumbers; myDel += MultiplyNumbers; Если бы он это сделал, то преобразование группы методов могло бы создать экземпляр его типа MyDelegate. Это преобразование группы методов, даже если группа перегрузок (включая универсальные перегрузки) состоит только из одной перегрузки. - person Jeppe Stig Nielsen; 22.02.2013
comment
Если вы дадите мне ссылку на какую-то документацию, я вам поверю. До тех пор я буду придерживаться исходной документации ECMA, в которой изложен мой предыдущий комментарий. В том же классе / структуре должна быть группа методов с тем же именем, чтобы мы могли преобразовать группу методов. - person Freeman; 22.02.2013
comment
@Freeman Если вы не думаете, что MyDelegate myDel = AddNumbers; (с именами, относящимися к вопросу) является преобразованием группы методов, тогда что бы это было? Прочтите Спецификацию языка C #, где начинается соответствующий раздел: Существует неявное преобразование (§6.1) из группы методов (§7.1) в совместимый тип делегата. Учитывая тип делегата D и выражение E, которое классифицируется как группа методов, существует неявное преобразование из E в D, если [...] Также попробуйте сказать var x = AddNumbers;. Компилятор ответит CS0815: Cannot assign method group to an implicitly-typed local variable - person Jeppe Stig Nielsen; 22.02.2013

Фактически все делегаты в C # являются MulticastDelegates, даже если они имеют только один метод в качестве цели. (Даже анонимные функции и лямбды являются MulticastDelegates, хотя по определению имеют только одну цель.)

MulticastDelegate - это просто базовый класс для всех видов ссылок на функции или методы в C #, независимо от того, содержат ли они одну или несколько целей.

Итак, это:

MyDelegate myDel = new MyDelegate(AddNumbers);

Устанавливает myDel в MulticastDelegate с одной целью. Но эта строка:

myDel += new MyDelegate(MultiplyNumbers);

Обновляет myDel до MulticastDelegate с двумя целями.

person JacquesB    schedule 02.07.2015

Многоадресные делегаты - это одна из функций делегатов, они объединяют ссылку на несколько методов и вызывают их последовательно. Это также называется цепочкой делегатов.

Ниже приведен пример делегатов многоадресной рассылки.

    // Declare Delegates
public delegate void MultiCast(int num1, int num2);

class Program
{
    public void Add(int num1, int num2)
    {
        Console.WriteLine(num1 + num2);
    }
    public  void Sub(int num1, int num2)
    {
        Console.WriteLine(num1 - num2);
    }
    public  void Mul(int num1, int num2)
    {
        Console.WriteLine(num1 * num2);
    }

    static void Main(string[] args)
    {
        MultiCast del1, del2, del3, multAddDel, multSubDel;
        del1 = new Program().Add;
        del2 = new Program().Sub;
        del3 = new Program().Mul;

    //`There are three ways to define the multicast delegate.`

        //1 way

        //Adding delegates 
        multAddDel = del1 + del2 + del3;
        multAddDel(10, 10);
        //Removing Delegates
        multSubDel = multAddDel - del3;
        multSubDel(10, 10);

        Console.WriteLine();
        Console.WriteLine("Second Way");

        //2 way

        MultiCast multAddDel1 = null;
        //Adding delegates 
        multAddDel1 += del1;
        multAddDel1 += del2;
        multAddDel1 +=  del3;
        multAddDel1(10, 10);
        //Removing Delegates
        multAddDel1 -= del3;
        multAddDel1(10, 10);

        Console.WriteLine();
        Console.WriteLine("Third Way");

        //3 way

        MultiCast multAddDel2 = null;
        //Adding delegates 
        multAddDel2 = (MultiCast)Delegate.Combine(multAddDel2, del1);
        multAddDel2 = (MultiCast)Delegate.Combine(multAddDel2, del2);
        multAddDel2 = (MultiCast)Delegate.Combine(multAddDel2, del3);
        multAddDel2(10, 10);

        //Removing Delegates
        multAddDel2 = (MultiCast)
            Delegate.Remove(multAddDel2, del3);

        multAddDel2(10, 10);
        Console.ReadLine();
    }
}
person Sheo Dayal Singh    schedule 01.04.2017