2016-10-28 1 views
0

Декларирование событие требует делегата, абоненты будут следовать (насколько я знаю):Зачем заставлять подписчиков событий иметь определенную подпись на C#?

public delegate void SomeEventHandler(object source, EventArgs args); 
public event SomeEventHandler EventHappend; 

Но зачем нам нужен этот делегат? Почему бы не позволить любому методу с подписью подписываться на событие?

+2

Как отправитель события сможет определить аргументы? –

+0

Вы думаете о 'public delegate void SomeEventHandler (int someInt, string someString, object someObject);' и т. Д.? Ну, это возможно, просто не так часто. –

+0

@ vc74 - Почему я хочу, чтобы отправитель определялся в аргументах? – Sipo

ответ

2

Сохраняя ваш пример ...

class A 
{ 
    public event EventHappend; // Invalid C# but let's pretend it could work 

    public void DoSomething() 
    { 
    ... 
    if (EventHappend != null) 
    { 
     // What should ??? be replaced with? 
     EventHappend(???); 
    } 
    } 
} 

class B 
{ 
    public B() 
    { 
    new A().EventHappend += EventHandler; 
    } 

    public void EventHandler(int anInt) 
    ... 
} 

class C 
{ 
    public C() 
    { 
    new A().EventHappend += EventHandler; 
    } 

    public void EventHandler(string aString) 
    ... 
} 

Что нужно ??? быть замененным на обработку B и C (int или string в параметре)?

+0

Спасибо всем. Я выбрал этот ответ, потому что он был первым, но все говорят то же самое по-другому. Отличные ответы, теперь я понимаю. Еще раз спасибо! – Sipo

1

Поскольку вызывающий абонент ожидает, что сможет передать набор параметров вызываемому абоненту. Таким образом, как вызывающий, так и вызываемый должны договориться о каком-то контракте, который определяет набор параметров, которые ожидает абонент, и вызываемый абонент - это, возможно, делегат.

«Экземпляр» делегата говорит не что иное: посмотрите здесь, вот «указатель» на метод, который соответствует моей сигнатуре и, вызывая меня, вы можете выполнить этот метод.

Пример: вызывающий абонент хочет передать свой экземпляр, string и int для вызываемого абонента. Как это работает, если вызываемый только принял bool?

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

public void Method(object sender, EventArgs e); 

так, что следующее событие Синтаксис объявления всегда работает:

public event EventHandler<EventArgs> MyEvent; 

Но это во многих случаях требуется создать класс, полученный из EventArgs, если вы хотите передать любую полезную нагрузку вызываемому.

1

Почему бы не позволить любому методу подписки на какую-либо подпись?

Тогда как отправитель должен знать, какие аргументы передать подписчику?

Вы можете или не можете знать, это то, как вы поднимаете событие, которое вы объявленную в вашем вопросе:

EventHappened(this, new EventArgs()); 

Всякий раз, когда вы поднимаете событие, нужно передать аргументы его! Давайте предположим, что вы позволили любого рода способом, чтобы подписаться на событие, то я буду использовать этот метод, чтобы подписаться на EventHappened:

private void Foo(object sender, EventArgs e, int someNumber) { 
    Console.WriteLine(someNumber); 
} 

Когда событие происходит, что будет напечатано? Никто не знает! Отправитель события не передал аргумент int!

Можно сказать,

Тогда я просто передать дополнительный аргумент Int, когда я поднимаю событие!

Что делать, если есть другой метод, который также подписывается на событие, как это:

private void Bar(object sender, EventArgs e, List<string> myList) { 
    Console.WriteLine(myList); 
} 

Таким образом, ИНТ аргумент не совместим с List<string>!

«C# не Javascript Вы не можете просто передать 2 аргумента методу, который нуждается в 3.» - уборочная машина 2016

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

+0

Действительно понравился «* C# не Javascript. Вы не можете просто передать 2 аргумента методу, который нуждается в 3 - Sweeper 2016 *» :) Но так как вы могли передать два аргумента методу, которому нужно 3 в JS ?! – Sipo

+1

Попробуйте эту скрипку: https://jsfiddle.net/fx107prd/1/ @Sipo – Sweeper

+0

Это так опасно. – Sipo

Смежные вопросы