3

私はJosh Smith の CommandSink Exampleに取り組んでいますが、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

4 に答える 4

11

(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;
};
于 2009-04-21T07:13:49.167 に答える
1
base.CanExecute += (s, e) =>
                {
                    bool handled;
                    e.CanExecute = _commandSink.CanExecuteCommand(e.Command, e.Parameter, out handled);
                    e.Handled = handled;
                };

ここに表示されているのは、C# 3 の Lambda です。

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 行の式には中括弧は必要ありません。

于 2009-04-21T07:23:18.473 に答える
1

はい、(s, e) は署名です。関数には、イベントによって定義された署名が必要です (CommandBinding.CanExecute: http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.canexecute.aspx )。

この特定の例では、変数 s は使用されません。このイベントは、.NET の他のほとんどのイベントと同じデザイン パターンに従います。通常、最初のパラメーターにはイベントを発生させたインスタンスへの参照が含まれ、2 番目のパラメーターには EventArgs クラス (または EventArgs を継承するより特殊なクラス) が含まれます。この場合、2 番目のパラメーターは CanExecuteRoutedEventArgs 型のインスタンスになります (情報の解釈を誤っていない限り)。

于 2009-04-21T07:15:59.007 に答える
1

(s, e) は一種の署名ですが、その解釈は C# コンパイラからの推論に依存します。C# コンパイラは、Executed の型が ExecutedRoutedEventHandler であることを認識しており、これは と同等void delegate(object, ExecutedRoutedEventArgs)です。ラムダ式(s, e) => { ... }を見て、s は object 型でなければならず、e は ExecutedRoutedEventArgs 型でなければならず、式全体が (object, ExecutedRoutedEventArgs) から void への関数であることがわかります。

他の人が指摘したように、s が存在しない場合、匿名関数は ExecutedRoutedEventHandler に必要な署名に準拠しないため、存在します。一部の言語には、「このパラメーターは正式な技術的理由からここにある必要がありますが、私は興味がありません」という特別な表記法があります。C# はそうではないため、使用されていなくてもパラメーターに名前を付ける必要があります。

于 2009-04-21T07:18:07.113 に答える