Отличие событий и делегатов C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.07.06 08:20
Оценка: 18 (2)
#Имя: FAQ.dotnet.events.and.delegates
Здравствуйте, Аноним, Вы писали:

А>Правильно, ли я понимаю, что определив события, мы просто не можем нарушить целостность списка получателей, и вообще вносить в него изменения только операторами += и -=? Ну и, кроме того, всяческие выгоды от собственноручного определения методов add_... и remove_... ?


Кроме того, мы еще не можем извне класса узнать, кто еще подписан на событие, а также мы не можем извне класса вызвать это событие. Это лучше удовлетворяет требованиям ООП и защищает нас от потенциально опасных архитектурных решений. Рассмотрите следующий код:

using System;

public delegate void MyDelegate();

public class EventDeclarator
{
    public static MyDelegate PlainDelegate;
    public static event MyDelegate Event;
    
    public void FireEvent()
    {
        if (Event != null)
            Event(); // так работает

        if (PlainDelegate != null)
            PlainDelegate(); // так тоже работает
    }
}

public class Client
{
    public static void WhatCanIDoWithPlainDelegate()
    {
        EventDeclarator.PlainDelegate += new MyDelegate(Foo);
        // подписали метод Foo

        EventDeclarator.PlainDelegate = new MyDelegate(Bar);
        // подписали метод Bar, но при этом удалили других подписчиков, а они-то и не знают :)

        Delegate[] subscribers = EventDeclarator.PlainDelegate.GetInvocationList();
        // получили список всех подписчиков и теперь можем (через делегаты) дергать даже приватные методы классов

        EventDeclarator.PlainDelegate();
        // вызвали "событие" извне определяющего класса
    }
    
    public static void WhatCanIDoWithEvent()
    {
        EventDeclarator.Event += new MyDelegate(Foo);
        // подписали метод Foo

        EventDeclarator.Event = new MyDelegate(Bar); // не компилируется
        Delegate[] subscribers = EventDeclarator.Event.GetInvocationList(); // не компилируется
        EventDeclarator.Event(); // не компилируется
    }
    
    private static void Foo() { }
    private static void Bar() { }
}
event delegate
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.