C#: действительно ли вызов является обработчиком событий явно действительно “хорошая вещь сделать”?

Оба window.pageYOffset и document.documentElement.scrollTop возвращают одинаковый результат во всех случаях.

Да, window.pageYOffset не поддерживается ниже IE 9.

Метод scrollTop () также может быть использован для получения вертикальной позиции полосы прокрутки конкретного элемента.

14
задан Rex M 15 September 2009 в 02:52
поделиться

6 ответов

Я согласен с ответом Рекса М , но я бы пошел еще дальше. Если вы используете шаблон MVC (или что-то подобное), представление делегирует нажатие кнопки контроллеру. Конечно, методы контроллеров могут быть вызваны из любого места в вашем классе - скажем, из вашего обратного вызова таймера.

Итак, вернемся к вашему исходному коду:

using System.Windows.Forms;

class MyForm : Form
{
    private Timer myTimer;
    private Button myButton;

    private MyController myController;

    public MyForm()
    {
        // ...
        // Initialize the components, etc.
        // ...

        myTimer.Tick += new EventHandler( myTimer_Tick );
        myButton.Click += new EventHandler( myButton_Click );

        myTimer.Start();
    }

    private void myTimer_Tick( object sender, EventArgs eventArgs )
    {
        myTimer.Stop();
        myController.SomeMethod()
    }

    private void myButton_Click( object sender, EventArgs eventArgs )
    {
        // All the stuff done here will likely be moved 
        // into MyController.SomeMethod()
        myController.SomeMethod();
    }
}

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

РЕДАКТИРОВАТЬ: Добавлено в ответ на комментарии OP

В фундаментальных принципах проектирования программного обеспечения говорится о взаимосвязи и согласованности. Важно отметить, что мы стремимся минимизировать взаимосвязь между компонентами при максимальной согласованности, так как это приводит к созданию более модульной и удобной в обслуживании системы. Такие шаблоны, как MVC, и принципалы, такие как Open / Closed Principal, основываются на этих основах, предоставляя разработчику более ощутимые шаблоны реализации.

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

Некоторые соответствующие ссылки:

7
ответ дан 1 December 2019 в 07:13
поделиться

myButton.PerformClick () , вероятно, немного лучше, если вам не нужно передавать аргументы событий. Иногда вам просто нужно смоделировать щелчок.

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

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

5
ответ дан 1 December 2019 в 07:13
поделиться

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

void ButtonClickEventHandler(...)
{
    UserData userData = //determine user data from event data
    DoUserThing(userData);
}

void DoUserThing(UserData userData)
{
    //do stuff
}

void SomeOtherMethod()
{
    UserData userData = //get userdata from some other source
    DoUserThing(userData);
}

(Это очень общий пример. В правильном приложении все должно быть разделено на разные классы по признаку .)

24
ответ дан 1 December 2019 в 07:13
поделиться

Этот код увеличивает вероятность проблем, если другой кодировщик работает с методом myButton_Click.

Что, если бы я пришел, чтобы настроить реализацию обработчика myButton.Click? Я мог бы предположить, что объект отправителя - это кнопка, и попытаться выполнить приведение:

Button b = (Button)sender;

Я не знаю, не читая остальную часть реализации класса, что я не всегда получаю кнопку в качестве отправителя.

Итак, моя точка зрения составляет: -1 для удобства обслуживания, так как нарушаются предположения о том, какие объекты будут передаваться как параметры myButton_Click.

1
ответ дан 1 December 2019 в 07:13
поделиться

Короткий ответ: зачем имитировать нажатие кнопки, вызывая обработчик напрямую? Если вы хотите связать оба метода с одним и тем же событием, вы просто подключите его. Обработчики событий являются многоадресными делегатами, что означает, что вы можете добавить более одного из них. Подключение события более одного раза совершенно приемлемо.

    myTimer.Tick += myTimer_Tick;
    myTimer.Tick += myButton_Click;

    myButton.Click += myButton_Click;

Независимо от того, является ли это WTF, - это инженерный вызов, который мы не можем сделать из короткого фрагмента кода. Однако, судя по вашим комментариям, это пахнет WTF. Формы или любой пользовательский интерфейс никогда не должны обрабатывать бизнес-логику. Они должны быть осведомлены о бизнес-логике до некоторой степени (как при валидации), но они не инкапсулируют / не применяют логику сами.

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

В конце концов вы столкнетесь с некоторыми высокоуровневыми шаблонами, такими как MVC (модель-представление-контроллер) и MVP (модель-представление-презентатор), которые шаг за рамки простого наслоения. Если вы последуете им, вы получите хорошее разделение проблем.

Я согласен с принятым ответом, но сразу переходя к «Использовать MVC», вот код, который не иллюстрирует MVC, без объяснения, почему это небольшой культ карго. для меня.

1
ответ дан 1 December 2019 в 07:13
поделиться

Особенности событий в C # (и инфраструктура .Net в целом - это делегат, который является эквивалентом указателя на функцию в C / C ++. Метод, прикрепленный к самому событию, не особенным в любом случае и должен быть доступен из любого места.

Обновление: возможно, мне следовало быть более многословным, но я думал, что моего использования «следует» вместо «может» или «может» будет достаточно. Я утверждаю, что обработчики событий должны вызываться, когда требуются реализуемые ими функции, вместо того, чтобы они становились оболочками для методов, которые «выполняют свою работу». Чем меньше вызовов методов у вас в стеке, тем лучше вы будете, особенно с влияние на производительность обработки исключений .Net.

0
ответ дан 1 December 2019 в 07:13
поделиться
Другие вопросы по тегам:

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