2009-04-21 31 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采用委托类型以及它的参数是什么类型)。

=>表示要执行的函数,对于简单的单行表达式,通常不需要花括号。

相关问题