другое использование делегата - PullRequest
3 голосов
/ 01 сентября 2009

Возможный дубликат:
В чем разница между делегатом и событиями?

Возможен дубликат:
Разница между событиями и делегатами и соответствующими приложениями

(скопировано с этого дубликата )

Когда мне нужно поднять событие, я делаю это

public delegate void LogUserActivity(Guid orderGUID);
public event LogUserActivity ActivityLog;

даже это работает

public delegate void LogUserActivity(Guid orderGUID);
public LogUserActivity ActivityLog;

В чем разница между двумя из них

Ответы [ 5 ]

3 голосов
/ 01 сентября 2009

Здесь есть три вещи:

  • Объявление делегата тип
  • Создание общедоступной переменной с типом делегата
  • Создание открытого события с типом делегата

Переменная - это обычная переменная - любой может читать из нее, присваивать ей и т. Д. Событие предоставляет только возможности подписки / отмены подписки для внешнего мира. * * * * * * * * * * * * * * * * * * * * * * [*] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *, Как показано здесь, по сути, имеет поведение по умолчанию «подписаться / отписаться», хранящееся в поле с тем же именем. Внутри объявленного класса вы получаете доступ к полю; снаружи вы получите доступ к событию.

У меня есть статья о событиях и делегатах, которая объясняет более подробно.

РЕДАКТИРОВАТЬ: Чтобы ответить на комментарий, вы можете легко инициализировать событие в виде поля с помощью обработчика "no-op":

public event LogUserActivity ActivityLog = delegate{};
1 голос
/ 01 сентября 2009

События и публичные делегаты отличаются друг от друга тем, что в большинстве случаев я не могу использовать публичные делегаты:

Event: obj.ActivityLog = null; // неверно

Публичный делегат: obj.ActivityLog = null; // действителен

Это имеет значение, потому что я хочу, чтобы подписчик только добавлял / удалял себя из списка в большинстве случаев. Я не хочу, чтобы другие объекты отцепляли события от других подписчиков.

В тех случаях, когда делегат является менее значимым событием, а скорее обратным вызовом, я склонен использовать для этого открытые методы и не допускать непосредственного раскрытия открытого делегата:

obj.RegisterActivityCallback (...)

1 голос
/ 01 сентября 2009

Событие - это абстракция над делегатом, так же как свойство является абстракцией над полем. И, как и свойство, событие позволяет вам получить полный контроль над тем, что происходит при добавлении / удалении обработчика:

public event LogUserActivity ActivityLog
{
    add { ... }
    remove { ... }
}

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

0 голосов
/ 01 сентября 2009

для добавления ко всем предыдущим ответам, событие является делегатом определенного типа. Делегат - это тип, который предназначен для того, чтобы действовать как «умный» указатель на функцию или, иначе говоря, как «умная» оболочка для указателя на функцию, которая позволяет компилятору интеллектуально определять во время компиляции, является ли функция ( s) вы придерживаетесь делегата в соответствии с тем, как вы используете делегата (согласованность основана на сигнатуре функции).

Событие - это делегат с определенной сигнатурой, в частности, тот, который ничего не возвращает (возвращает void) и принимает два параметра, System.object, для хранения ссылки на любой объект, вызвавший событие, и экземпляр некоторого типа, производного от System.EventArgs, для хранения любых других данных, которые событие должно передать вместе с инициатором в обработчик.

0 голосов
/ 01 сентября 2009

В первом случае вы можете назначить несколько слушателей для вашего события ActivityLog, как в:

logger.ActivityLog += new LogUserActivity(Listener1);
logger.ActivityLog += new LogUserActivity(Listener2);

Оба метода (Listener1 и Listener2) будут вызваны при возникновении события. Во втором случае вы создаете не событие, а делегата. В этом случае вы можете назначить только одного слушателя:

logger.ActivityLog = new LogUserActivity(Listener1);

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

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