Может кто-то объяснить эту структуру C #: base.Executed + = (s, e) => - PullRequest
3 голосов
/ 21 апреля 2009

Я работаю через Пример CommandSink Джоша Смита , и структуры base.Executed += (s, e) =>... бросают меня, кто-нибудь может помочь сделать этот кристально чистый?

что я понимаю:

  • base.CanExecute - событие в унаследованном классе CommandBinding
  • + = добавляет делегата к этому событию
  • делегат - это анонимная функция, которая следует за этой строкой

что я не понимаю:

  • является (s, e) сигнатурой этой функции?
  • где используется переменная s?

Вот код в контексте:

public class CommandSinkBinding : CommandBinding
    {
        #region CommandSink [instance property]

        ICommandSink _commandSink;

        public ICommandSink CommandSink
        {
            get { return _commandSink; }
            set
            {
                if (value == null)
                    throw new ArgumentNullException("Cannot set CommandSink to null.");

                if (_commandSink != null)
                    throw new InvalidOperationException("Cannot set CommandSink more than once.");

                _commandSink = value;

                base.CanExecute += (s, e) =>
                    {
                        bool handled;
                        e.CanExecute = _commandSink.CanExecuteCommand(e.Command, e.Parameter, out handled);
                        e.Handled = handled;
                    };

                base.Executed += (s, e) =>
                    {
                        bool handled;
                        _commandSink.ExecuteCommand(e.Command, e.Parameter, out handled);
                        e.Handled = handled;
                    };
            }
        } 
        ...

Ответы [ 4 ]

11 голосов
/ 21 апреля 2009

(s, e) - подпись параметра метода для обработчика событий (в данном случае это определенный аномальный метод)

думаю (object Sender, EventArgs e)

Параметр s просто не используется в остальной части метода, что нормально. Он должен быть там, чтобы соответствовать ожидаемой подписи

base.CanExecute += (s, e) =>
                    {
                        bool handled;
                        e.CanExecute = _commandSink.CanExecuteCommand(e.Command, e.Parameter, out handled);
                        e.Handled = handled;
                    };

эквивалентно действию

base.CanExecute += new EventHandler(myMethod_CanExecute);

///....
protected void myMethod_CanExecute(object sender, EventArgs e)
{
    bool handled;
    e.CanExecute = _commandSink.CanExecuteCommand(e.Command, e.Parameter, out handled);
    e.Handled = handled;
};
1 голос
/ 21 апреля 2009
base.CanExecute += (s, e) =>
                {
                    bool handled;
                    e.CanExecute = _commandSink.CanExecuteCommand(e.Command, e.Parameter, out handled);
                    e.Handled = handled;
                };

То, что вы видите здесь, это лямбда в C # 3.

В C # 2 это будет: -

    base.CanExecute += delegate(object s, EventArgs e)
                {
                    bool handled;
                    e.CanExecute = _commandSink.CanExecuteCommand(e.Command, e.Parameter, out handled);
                    e.Handled = handled;
                };

C # 3 допускает это (s, e) сжатие, поскольку оно может подразумевать типы с правой стороны (он может видеть, что CanExecute принимает тип делегата и какие типы имеют его параметры).

=> выражает функцию для выполнения, часто скобки не нужны для простого однострочного выражения.

1 голос
/ 21 апреля 2009

(s, e) является своего рода сигнатурой, но ее интерпретация зависит от вывода компилятора C #. Компилятор C # знает, что тип Executed - ExecutedRoutedEventHandler, что эквивалентно void delegate(object, ExecutedRoutedEventArgs). Он видит лямбда-выражение (s, e) => { ... } и выясняет, что s должен иметь тип object, e должен иметь тип ExecutedRoutedEventArgs, а все выражение является функцией от (object, ExecutedRoutedEventArgs) до void.

Как уже отмечали другие, s существует, потому что если бы его не было, анонимная функция не соответствовала бы подписи, требуемой ExecutedRoutedEventHandler. В некоторых языках есть специальное обозначение: «Этот параметр должен быть здесь по формальным техническим причинам, но я не заинтересован в нем». C # нет, поэтому он должен называть параметр, даже если он не используется.

1 голос
/ 21 апреля 2009

Да, (s, e) является подписью. Функция должна иметь подпись, определенную событием (CommandBinding.CanExecute: http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.canexecute.aspx).

В этом конкретном примере переменная s не используется. Событие следует тому же шаблону проектирования, что и большинство других событий в .NET. Первый параметр обычно содержит ссылку на экземпляр, вызвавший событие, второй параметр содержит класс EventArgs (или более специализированный класс, который наследует EventArgs). В этом случае вторым параметром будет экземпляр типа CanExecuteRoutedEventArgs (если только я неправильно истолковал какую-либо информацию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...