Каковы преимущества наличия событий, соответствующих Сетевым инструкциям?

Я понимаю, как использовать События согласно Сетевым инструкциям по Платформе, но каковы преимущества использования этого шаблона?

http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx:

Инструкции по Платформе.NET указывают, что тип делегата, используемый для события, должен взять два параметра, "объектный источник" параметр, указывающий на источник события и "e" параметр, который инкапсулирует любую дополнительную информацию о событии. Тип "e" параметра должен произойти из класса EventArgs. Для событий, которые не используют дополнительной информации, Платформа.NET уже определила соответствующий тип делегата: EventHandler.

a) Я вижу некоторые преимущества в использовании "объектного источника" значение как первый параметр, так как существуют ситуации, где нескольким объектам можно было установить их события на тот же метод. Таким образом, если, например, у нас есть 10 объектов и если все 10 объектов устанавливают свои события на обработчик событий M, то в M мы можем использовать “объектного отправителя” значение параметра для идентификации инициатора вызова события.

  • Но насколько я могу сказать”, объектный источник” параметр только полезен, если событие было сгенерировано в методе экземпляра. Таким образом, если событие было сгенерировано в статическом методе, то “объектный источник” параметр бесполезен?!

b) Есть ли другие преимущества использования событий с соответствием с Сетевыми инструкциями по Платформе?

c) Независимо от того, что преимущества могут быть, почему они-взвесили бы проблему необходимости к

  • напишите дополнительный код для помещения желаемых аргументов в объект, полученный из EventArgs
  • напишите дополнительный код в обработчиках событий для извлечения информации из объекта, полученного из EventArgs?

спасибо

7
задан AspOnMyNet 17 February 2010 в 17:49
поделиться

5 ответов

Насколько я понимаю, есть два основных преимущества:

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

Первый пункт должен быть довольно очевидным и не требует особой проработки.

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

Обновление
Ответ на вопросы:

Я не понимаю, что вы имеете в виду, говоря «возможность расширять EventArgs без изменения подписи события» ?!

Возьмем для примера следующий класс:

public class SomeClass
{
    public event EventHandler<FileEventArgs> SomethingHappened;
}
public class FileEventArgs : EventArgs
{
    public FileEventArgs(string filename)
    {
        Filename = filename;
    }
    public string Filename { get; private set; }
}

Затем у нас есть потребитель, который прослушивает событие SomethingHappened :

static void SomethingHappenedHandler(object sender, FileEventArgs e)
{
    // do something intelligent
}

Теперь предположим, что мы хотим расширить информацию, которую мы передать событие с информацией о том, что произошло с файлом:

public enum WhatHappened
{
    Copy,
    Rename,
    Delete
}
public class FileEventArgs : EventArgs
{
    public FileEventArgs(string filename, WhatHappened whatHappened)
    {
        Filename = filename;
        WhatHappened = whatHappened;
    }
    public string Filename { get; private set; }
    public WhatHappened WhatHappened { get; private set; }
}

Теперь, если бы мы выбрали отправку имени файла в качестве параметра в самом событии, нам нужно было бы изменить подпись события, добавив еще один параметр, что фактически нарушит все код, который прослушивает событие.Но поскольку мы в приведенном выше коде просто добавили еще одно свойство к классу FileEventArgs , подпись остается неизменной, и нет необходимости обновлять слушателей (если они не хотят использовать только что добавленное свойство, то есть) .

Я пишу, предполагая, что если событие вызывается внутри статического метода, то параметр «источник объекта» бесполезен ?!

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

10
ответ дан 6 December 2019 в 06:36
поделиться

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

/^[0-9]+$/.test(input);

Это возвращает значение true, если ввод является числовым или ложным, если нет.

или для ключевого кода события, простое использование ниже:

     // Allow: backspace, delete, tab, escape, enter, ctrl+A and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
         // Allow: Ctrl+A
        (e.keyCode == 65 && e.ctrlKey === true) || 
         // Allow: home, end, left, right
        (e.keyCode >= 35 && e.keyCode <= 39)) {
             // let it happen, don't do anything
             return;
    }

    var charValue = String.fromCharCode(e.keyCode)
        , valid = /^[0-9]+$/.test(charValue);

    if (!valid) {
        e.preventDefault();
    }
-121--1764937-

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

-121--3783582-

Если вы придерживаетесь руководящих принципов .NET Framework, не только для событий, но и для всего, кто-то, кто должен прочитать ваш код или использовать вашу библиотеку, узнает его, что упростит для него задачу. Это всегда хорошо, так как вы должны писать код для своих читателей, а не для вашего удобства. Хорошо с .NET то, что есть некоторые стандартные руководящие принципы с самого начала, в отличие от тысяч конвенций для C++ и тому подобное, и большинство людей знают это и применяют его.

Дополнительным преимуществом стандартной сигнатуры обработчика событий является то, что можно назначить менее специализированные обработчики событий (например, EventHandler ) событию более специализированного типа, упрощая разработку, если кому-то не нужны дополнительные данные. Это также упрощает добавление обработчиков событий через отражение, что может быть полезно при определенных обстоятельствах. (как браузер иерархии объектов для какой-либо объектной модели) - Я могу заверить вас, что код для обработки любого события через Отражение - это сложная вещь, которую я решил, выдавая код IL для каждого события, которое я всегда считал последним средством.

Как писал Фредрик Мёрк в то же время, это также облегчает расширение вашего события позже, добавляя параметры только к вашему производному от EventArgs классу, а не к каждому обработчику событий.

8
ответ дан 6 December 2019 в 06:36
поделиться

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

почему?

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

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

поэтому, как обычно, «это зависит» и «используйте свое собственное мнение» применяются: -)

3
ответ дан 6 December 2019 в 06:36
поделиться

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

4
ответ дан 6 December 2019 в 06:36
поделиться

Вы можете использовать делегат Generic Event Handler (EventHandler< TEventArgs >), если вы используете стандартные сигнатуры событий и ваши аргументы события наследуются от eventargs.

public event EventHandler<MyCustomEventArgs> MyEvent;

http://msdn.microsoft.com/en-us/library/db0etb8x.aspx

2
ответ дан 6 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

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