+ = оператор с событиями - PullRequest
20 голосов
/ 28 июля 2010
public void Bar()
{
    Foo foo = new Foo();
    **foo.MyEvent += foo_MyEvent;**
    foo.FireEvent();        
}

void foo_MyEvent(object sender, EventArgs e)
{
    ((Foo)sender).MyEvent -= foo_MyEvent;
}

Эй, я немного незнаком с событиями, может кто-нибудь сказать мне, что оператор + = делает с событиями?

Ответы [ 6 ]

38 голосов
/ 28 июля 2010

+= подписывается на событие. Делегат или метод в правой части += будут добавлены во внутренний список, за которым отслеживает событие, и когда класс-владелец запускает это событие, будут вызваны все делегаты в списке.

20 голосов
/ 28 июля 2010

Ответ, который вы приняли, является хорошей упрощенной версией того, что делает +=, но это не полная история.

Оператор += вызывает метод add для события. Аналогично -= звонки удалить. Это обычно приводит к добавлению делегата во внутренний список обработчиков, которые вызываются при запуске события, но не всегда .

Вполне возможно определить add, чтобы сделать что-то еще. Этот пример может помочь продемонстрировать, что происходит, когда вы звоните +=:

class Test
{
    public event EventHandler MyEvent
    {
        add
        {
            Console.WriteLine("add operation");
        }

        remove
        {
            Console.WriteLine("remove operation");
        }
    }       

    static void Main()
    {
        Test t = new Test();

        t.MyEvent += new EventHandler (t.DoNothing);
        t.MyEvent -= null;
    }

    void DoNothing (object sender, EventArgs e)
    {
    }
} 

Выход:

add operation
remove operation

См. Статью Джона Скита о событиях и делегатах для получения дополнительной информации.

1 голос
/ 22 июня 2019

Одной из замечательных особенностей делегатов является то, что вы можете объединить их вместе.Это называется многоадресной рассылкой.Вы можете использовать оператор + или + =, чтобы добавить другой метод в список вызовов существующего экземпляра делегата.Аналогично, вы также можете удалить метод из списка вызовов, используя оператор присваивания декремента (- или - =).Эта функция служит основой для событий в C # .Ниже приведен пример многоадресного делегата.

class Program
{
    static void Hello(string s)
    {
        Console.WriteLine("  Hello, {0}!", s);
    }

    static void Goodbye(string s)
    {
        Console.WriteLine("  Goodbye, {0}!", s);
    }

    delegate void Del(string 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;

        Console.WriteLine("Invoking delegate a:");
        a("A");
        Console.WriteLine("Invoking delegate b:");
        b("B");
        Console.WriteLine("Invoking delegate c:");
        c("C");
        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!
        */

        Console.ReadLine();
    }
}

Все это возможно, поскольку делегаты наследуются от класса System.MulticastDelegate, который, в свою очередь, наследуется от System.Delegate.Из-за этого вы можете использовать члены, определенные в этих базовых классах для ваших делегатов.Вы можете узнать больше об этом в статье Делегаты и события в C # .NET

1 голос
/ 07 апреля 2011

Событие - это просто неизменный список делегатов (то есть подписок, которые будут вызываться, когда что-то публикует / вызывает это событие). Вы можете утверждать, что мы могли бы использовать список вместо. Если бы мы пошли таким путем, кто-то мог бы закалиться с нашими подписчиками.

В приведенном выше сценарии, где вы используете Список, вы можете сделать:

lstDelegate = newDelegate

и вы стерли существующих подписчиков (lstDelegate теперь содержит только ваш ответный вызов делегата).

Чтобы остановить это, у нас есть Событие . Когда вы используете событие, complier не позволяет вам этого делать, вам разрешено добавлять / удалять свой собственный делегат только с помощью + = и - =. Вот так я и пытаюсь дифференцировать это. надеюсь, это поможет.

1 голос
/ 28 июля 2010

В этом случае метод foo_MyEvent будет запускаться при вызове этого события (поэтому вы подписываетесь на событие в строке 4)

0 голосов
/ 28 июля 2010

Добавляет обработчик к событию. Это означает, что метод с правой стороны от оператора будет вызываться при возникновении события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...