.NET EventHandlers - Универсальный или нет?

21
задан Chris Marasti-Georg 24 September 2008 в 23:02
поделиться

9 ответов

Делегат следующей формы был добавлен, так как Платформа.NET 2.0

public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs

, к которому Вы приближаетесь, идет немного далее, так как Вы предоставляете out-of-the-box реализацию EventArgs с единственным элементом данных, но это испытывает недостаток в нескольких свойствах исходной идеи:

  1. Вы не можете добавить больше свойств к данным о событии, не изменяя зависимый код. Необходимо будет изменить подпись делегата, чтобы предоставить больше данных подписчику события.
  2. Ваш объект данных универсален, но это также "анонимно", и при чтении кода, необходимо будет дешифровать свойство "Item" от использований. Это нужно назвать согласно данным, которые это обеспечивает.
  3. Используя дженерики таким образом Вы не можете сделать параллельную иерархию EventArgs, когда у Вас есть иерархия лежания в основе (объекта) типы. Например, EventArgs< BaseType> не базовый тип для EventArgs< DerivedType> даже если BaseType является основой для DerivedType.

Так, я думаю, что лучше использовать универсальный EventHandler< T> но все еще имейте пользовательские классы EventArgs, организованные согласно требованиям модели данных. С Visual Studio и расширениями как ReSharper, это - только вопрос немногих команд для создания нового класса как этот.

27
ответ дан 2 revs 29 November 2019 в 06:46
поделиться

Для создания универсального объявления события легче я создал несколько фрагментов кода для него. Использовать их:

  • Копия целый отрывок.
  • Вставка это в текстовом файле (например, в Блокноте).
  • Сохранили файл с .snippet расширением.
  • Помещенный .snippet файл в Ваш соответствующий каталог отрывка, такой как:

Visual Studio 2008\Code Snippets\Visual C#\\Мои Фрагменты кода

Вот являются тем, который использует пользовательский класс EventArgs с одним свойством:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Generic event with one type/argument.</Title>
            <Shortcut>ev1Generic</Shortcut>
            <Description>Code snippet for event handler and On method</Description>
            <Author>Kyralessa</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
        <Literal>
          <ID>type</ID>
          <ToolTip>Type of the property in the EventArgs subclass.</ToolTip>
          <Default>propertyType</Default>
        </Literal>
        <Literal>
          <ID>argName</ID>
          <ToolTip>Name of the argument in the EventArgs subclass constructor.</ToolTip>
          <Default>propertyName</Default>
        </Literal>
        <Literal>
          <ID>propertyName</ID>
          <ToolTip>Name of the property in the EventArgs subclass.</ToolTip>
          <Default>PropertyName</Default>
        </Literal>
        <Literal>
          <ID>eventName</ID>
          <ToolTip>Name of the event</ToolTip>
          <Default>NameOfEvent</Default>
        </Literal>
            </Declarations>
      <Code Language="CSharp"><![CDATA[public class $eventName$EventArgs : System.EventArgs
      {
        public $eventName$EventArgs($type$ $argName$)
        {
          this.$propertyName$ = $argName$;
        }

        public $type$ $propertyName$ { get; private set; }
      }

      public event EventHandler<$eventName$EventArgs> $eventName$;
            protected virtual void On$eventName$($eventName$EventArgs e)
            {
                var handler = $eventName$;
                if (handler != null)
                    handler(this, e);
            }]]>
      </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

И вот тот, который имеет два свойства:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Generic event with two types/arguments.</Title>
      <Shortcut>ev2Generic</Shortcut>
      <Description>Code snippet for event handler and On method</Description>
      <Author>Kyralessa</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>type1</ID>
          <ToolTip>Type of the first property in the EventArgs subclass.</ToolTip>
          <Default>propertyType1</Default>
        </Literal>
        <Literal>
          <ID>arg1Name</ID>
          <ToolTip>Name of the first argument in the EventArgs subclass constructor.</ToolTip>
          <Default>property1Name</Default>
        </Literal>
        <Literal>
          <ID>property1Name</ID>
          <ToolTip>Name of the first property in the EventArgs subclass.</ToolTip>
          <Default>Property1Name</Default>
        </Literal>
        <Literal>
          <ID>type2</ID>
          <ToolTip>Type of the second property in the EventArgs subclass.</ToolTip>
          <Default>propertyType1</Default>
        </Literal>
        <Literal>
          <ID>arg2Name</ID>
          <ToolTip>Name of the second argument in the EventArgs subclass constructor.</ToolTip>
          <Default>property1Name</Default>
        </Literal>
        <Literal>
          <ID>property2Name</ID>
          <ToolTip>Name of the second property in the EventArgs subclass.</ToolTip>
          <Default>Property2Name</Default>
        </Literal>
        <Literal>
          <ID>eventName</ID>
          <ToolTip>Name of the event</ToolTip>
          <Default>NameOfEvent</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[public class $eventName$EventArgs : System.EventArgs
      {
        public $eventName$EventArgs($type1$ $arg1Name$, $type2$ $arg2Name$)
        {
          this.$property1Name$ = $arg1Name$;
          this.$property2Name$ = $arg2Name$;
        }

        public $type1$ $property1Name$ { get; private set; }
        public $type2$ $property2Name$ { get; private set; }
      }

      public event EventHandler<$eventName$EventArgs> $eventName$;
            protected virtual void On$eventName$($eventName$EventArgs e)
            {
                var handler = $eventName$;
                if (handler != null)
                    handler(this, e);
            }]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

можно следовать за шаблоном для создания их со столькими свойствами, сколько Вам нравится.

9
ответ дан Ryan Lundy 29 November 2019 в 06:46
поделиться

Нет, я не думаю, что это - неправильный подход. Я думаю, что это даже рекомендуется в [фантастическом] книжном Руководстве по проектированию Платформы . Я делаю то же самое.

8
ответ дан swilliams 29 November 2019 в 06:46
поделиться

Это - корректная реализация. Это было добавлено к Платформе.NET (mscorlib), так как дженерики сначала прибыли доступные (2.0).

Для больше на его использовании и реализации см. MSDN: http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

3
ответ дан David Walschots 29 November 2019 в 06:46
поделиться

Так как.NET 2.0

EventHandler<T>

была реализована.

2
ответ дан mattlant 29 November 2019 в 06:46
поделиться

В первый раз, когда я видел этот небольшой шаблон, я использовал Составной объект Блок приложений UI от Шаблонов MS & группа Методов.

Это не бросает красного флага в меня; на самом деле это - даже умный способ усилить дженерики для следования правило DRY.

3
ответ дан Romain Verdier 29 November 2019 в 06:46
поделиться

Можно найти Универсальный EventHandler на MSDN http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

, я использовал универсальный EventHandler экстенсивно, и смог предотвратить так называемый "Взрыв Типов (Классы)" Проект, был сохранен меньшим и легче перейти вокруг.

Придумывающий новое интуитивное делегат к неуниверсальному делегату EventHandler является болезненным, и перекрытие с существующими типами, Добавляющими "*EventHandler" к новому имени делегата, не помогает многому, по-моему

2
ответ дан dance2die 29 November 2019 в 06:46
поделиться

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

РЕДАКТИРОВАНИЕ /

не получило различие там первоначально. Пока Вы пасуете назад класс, который наследовался EventArgs, который Вы, я не вижу проблемы. Я был бы заинтересован, не обертывали ли Вы resultfor причины пригодности для обслуживания. Я все еще говорю, что это выглядит хорошим мне.

1
ответ дан Chuck 29 November 2019 в 06:46
поделиться

Использовать экземпляры универсального обработчика событий

До .NET Framework 2.0 для передачи настраиваемой информации обработчику событий необходимо было объявить новый делегат в котором указан класс, производный от класса System.EventArgs. Это больше не верно в .NET

Framework 2.0, в котором появился делегат System.EventHandler ). Этот универсальный делегат позволяет использовать любой класс, производный от EventArgs, с обработчиком событий.

1
ответ дан 29 November 2019 в 06:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: