2009-04-21 83 views
3

我工作過Josh Smith's CommandSink Examplebase.Executed += (s, e) =>...結構都扔我,有人可以幫助使這個晶瑩剔透?有人可以解釋這個C#結構:base.Executed + =(S,E)=>

我的理解:

  • base.CanExecute是在繼承的類中的CommandBinding事件
  • 的+ =是增加委託該事件
  • 委託是匿名函數那條線

我不明白:

  • 是(s,e)是該函數的簽名?
  • 其中是使用的變量?

這是在上下文中的代碼:

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; 
        }; 
      } 
     } 
     ... 

回答

11

(s, e)是事件處理程序方法的參數簽名(在這種情況下的已定義的anoymous法)

認爲(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; 
}; 
+0

所以你也可以寫(發送者,e)甚至是(whatevernnn,e),它只是一個佔位符,對嗎? – 2009-04-21 07:15:54

+0

正確。 (s,e)或(jimbob,blahvar)簽名就是您對參數的命名約定,以便您可以在匿名方法聲明的其餘部分引用它們。但是你應該堅持一些像(s,e)/(sender,e)/(sender,args)這樣合理明顯的東西 – 2009-04-21 07:20:26

1

是,(S,E)是簽名的等價物。該函數必須具有事件定義的簽名(CommandBinding.CanExecute:http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.canexecute.aspx)。

在這個特定的例子中,變量s沒有被使用。事件遵循與.NET中大多數其他事件相同的設計模式。第一個參數通常包含對引發事件的實例的引用,第二個參數包含EventArgs類(或繼承EventArgs的更專用的類)。在這種情況下,第二個參數將是CanExecuteRoutedEventArgs類型的一個實例(除非我誤解了任何信息)。

1

(s,e)是簽名的種類 - 但其解釋取決於C#編譯器的推理。 C#編譯器知道Executed的類型是ExecutedRoutedEventHandler,相當於void delegate(object, ExecutedRoutedEventArgs)。它看到了lambda表達式(s, e) => { ... }並指出s必須是object類型,e必須是ExecutedRoutedEventArgs類型,整個表達式是從(object,ExecutedRoutedEventArgs)到void的函數。

正如其他人已經注意到的,因爲如果它不存在,匿名函數將不符合ExecutedRoutedEventHandler所需的簽名。有些語言有一個特殊的表示法,說「這個參數必須出於正式的技術原因,但我對它不感興趣。」 C#沒有,所以它必須命名參數,即使它沒有被使用。

+0

OK,在System.Windows.Input中ExecutedRoutedEventHandler被這樣定義:public delegate void ExecutedRoutedEventHandler(object sender,ExecutedRoutedEventArgs e )確定簽名,有道理 – 2009-04-21 07:21:55

1
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採用委託類型以及它的參數是什麼類型)。

=>表示要執行的函數,對於簡單的單行表達式,通常不需要花括號。