Является ли «отправитель» в Button_Click (отправитель объекта ... действительно отправителем? - PullRequest
3 голосов
/ 19 марта 2009

Тед Фэйсон в подкасте по разработке программного обеспечения на основе событий упомянул, что объекты "отправитель" и "сам" в операторах событий .NET, C ++ и Java, такие как:

private void Button_Click(object sender, RoutedEventArgs e)

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

Я правильно его понял (поскольку при отладке «отправитель» действительно кажется исходным объектом).

Или же шаблоны общих событий в этих языках (например, общий обработчик кликов) тесно связаны, но они должны быть более разъединенными, например в композитных приложениях.

Он также упомянул, что, например, Вы не должны делать наследование от EventArgs, так как это приводит к взрыву классов, по одному на событие, которые переносят только несколько переменных. Много раз по его мнению, вы можете просто отправить строку, например. Он отметил, что это мнение противоположно тому, что предлагает Microsoft Patterns and Practices.

Есть мысли по поводу этих областей?

Ответы [ 2 ]

1 голос
/ 19 марта 2009

В большинстве случаев sender - это Button (или что-то еще), вызвавшее событие. Есть некоторые случаи, когда это не дело - например, (возможно, ленивое) сквозное событие:

class Foo {
   private Bar bar;
   public Foo(Bar bar) {
       this.bar = bar;
   }
   public event EventHandler SomeEvent {
       add {bar.SomeEvent += value;}
       remove {bar.SomeEvent -= value;}
   }
   //...
}

Здесь, если мы подпишемся на foo.SomeEvent, мы на самом деле вернем событие, инициированное экземпляром Bar, поэтому sender не будет быть foo. Но это возможно потому, что мы неправильно реализовали Foo.SomeEvent.

Если честно, в большинстве случаев вам не нужно проверять sender; основное время это полезно, когда несколько элементов управления совместно используют обработчик. Как правило, вы должны предполагать, что отправителем является экземпляр, на который вы подписаны (для целей проверки на равенство ссылок).

Re EventArgs - стандартный шаблон (при создании нового типа события) рекомендует вам наследовать от этого. Я не рекомендую отклоняться от этого. Незначительная причина в том, что она позволяет использовать EventHandler<T>, но есть и другие причины отклонений. Кроме того, иногда достаточно того, чего ожидают другие люди; люди ожидают * EventArgs производное значение.

Тем не менее, раньше я проводил нестандартные события (в Push LINQ MiscUtil), но это было уже в очень необычной обстановке, поэтому оно не ощущалось неуместным.

1 голос
/ 19 марта 2009

Сначала - «отправитель» будет содержать ссылку на кнопку, которую вы нажали. Если у вас есть несколько кнопок, подключенных к одному и тому же событию, именно так вы видите, на какую из кнопок вы нажали (если вы не передаете что-либо в аргументах события, чтобы прочитать это).

Также я в некоторой степени согласен с тем, что написание новых eventargs, наследующих frmo EventArgs, может привести к взрыву классов - так что используйте с causion. Мне нравится просто вызывать EventArgs.Empty, а затем иметь код, перехватывающий явное событие, запрашивающее объект, вызвавший событие для данных. Что я имею в виду - как только вы поймаете событие, вместо того, чтобы читать данные из аргументов события, вы переходите к объекту, вызвавшему событие, и читаете те его свойства, которые вас интересуют. Это упрощает чтение того, что вам нужно Конечно, вы можете оказаться в ситуации, когда эти свойства изменяются между вызванным событием и чтением свойств.

...