6

我一直在阅读有关代表的MSDN 页面,它们看起来很简单。然后我正在查看一些使用它们的代码,我看到了这个:

 public delegate void NoArguments();
 public NoArguments Refresh = null;
 Refresh = new NoArguments( Reset );

这是第三行让我感到困惑。你怎么能当new代表?它不是对象,而是方法,或者更确切地说是方法的委托。根据 MSDN 页面上的示例,创建委托的实例是通过简单的分配,而不是分配。此外,当委托声明不带参数时,为什么new委托带参数?Reset

4

3 回答 3

4

关键字表示后面的delegate内容本质上是一个函数签名,因此,Refresh它有点像一个指向不带参数的函数的指针。然而,Refresh要给指针赋值,你必须给它一个指向的函数。在这种情况下,它是Reset函数。此外,该Reset函数必须不带任何参数。

此外,语法:

Refresh = Reset;

也是有效的,并且只是更正式语法的语法糖:

Refresh = new NoArguments(Reset);

在这两种情况下,您都可以通过调用 Refresh 来执行 Reset 函数:

Refresh();

但是请注意,如果您在Refresh()没有分配它的情况下执行,那么您可能会生成异常。防止这种情况的方法是检查它是否为空:

if (Refresh != null) Refresh();
else {
    // Refresh was never assigned
}
于 2013-07-09T04:02:11.487 回答
2

你可能认为委托就像一个函数类型:

  • 声明类型,函数返回 void 并且没有参数:

    public delegate void NoArguments();
    
  • 声明给定类型的变量并初始化它:

    public NoArguments Refresh = null;
    
  • 将新对象分配给您的变量。Object 实际上是一个 function Reset,它必须与您的委托具有相同的签名:

    Refresh = new NoArguments( Reset );
    

更新:

您可以查看以下链接以获取更多详细信息:C# Delegates

于 2013-07-09T04:03:07.650 回答
1

委托是“委托给一个方法”,也是一个对象。如果您查看NoArguments任何反编译器,您会发现它实际上是一个继承自 的类MulticastDelegate,具有多个方法(InvokeBeginInvokeEndInvoke)。

由于历史原因,C# 允许您使用new NoArguments(method). 然而,在现代版本中,它还支持method做同样事情的快捷符号。在这两种情况下,您实际上都有一个 in 类型的NoArguments对象Refresh

于 2013-07-09T04:05:32.110 回答