C#中的委托()方法的确切含义是什么?

时间:2018-12-27 10:40:59

标签: c# delegates

C#(我来自Java)中,我是一个新手,并且正在从事SharePoint项目。

在我的代码中,我对此方法有以下疑问:

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    lock (this)
    {
        try
        {
            SPSecurity.RunWithElevatedPrivileges(delegate ()
            {
                SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                DeleteExistingJob(JobName, parentWebApp);
            });
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

如您所见,此代码已执行到 delegate(){...} “块”中:

SPSecurity.RunWithElevatedPrivileges(delegate ()
{
    SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
    DeleteExistingJob(JobName, parentWebApp);
});

delegate()方法到底是什么意思?

在这里阅读:https://docs.microsoft.com/it-it/dotnet/csharp/language-reference/keywords/delegate

在我看来,这有点像声明“匿名”方法的方法,其中该方法的实现是 {...} 块中的代码。

这是正确的解释还是我遗漏了一些东西?

如果正确,此 delegate()方法的目的是什么?为什么我不将代码声明为经典方法?确切的目的是什么?

2 个答案:

答案 0 :(得分:5)

根据您引用的文档,delegate关键字用于两个目的:

  • 声明委托类型
  • 创建一个匿名方法,该方法将转换为委托实例

现在,您可以在常规方法中以匿名方法编写所有代码,然后使用方法组转换来创建委托实例,但这通常很烦人-特别是如果您想在匿名方法中使用任何局部变量或参数。

这就是为什么要使用匿名方法的原因-从C#3开始的任何情况下,您更有可能使用 lambda表达式

如果您没有使用匿名方法或lambda表达式,请考虑如何在示例中创建委托。您需要编写如下内容:

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    lock (this)
    {
        // Note: try/catch removed as it's pointless here, unless you're
        // *trying* to obscure the stack trace in case of an exception
        JobDeletionHelper helper = new JobDeletionHelper(properties);
        // Note that we're using a method group conversion here - we're not
        // invoking the method. We're creating a delegate which will invoke
        // the method when the delegate is invoked.
        SPSecurity.RunWithElevatedPrivileges(helper.DeleteJob);
    }
}
// We need this extra class because the properties parameter is *captured*
// by the anonymous method
class JobDeletionHelper
{
    private SPFeatureReceiverProperties properties;

    internal JobDeletionHelper(SPFeatureReceiverProperties properties)
    {
        this.properties = properties;
    }

    public void DeleteJob()
    {
        // This is the code that was within the anonymous method
        SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
        DeleteExistingJob(JobName, parentWebApp);
    }
}

如果您要询问委托人自己的目的,那是一个稍大的话题-但总而言之,它是将可执行代码表示为对象的功能,因此可以将其传递给其他代码来执行。 (如果有用,您可以将委托类型视为单方法接口。)

答案 1 :(得分:2)

  

在我看来,这有点像声明“匿名”的方式   方法,其中此方法的实现是将代码插入   {...}阻止。

是的,这很重要!

  

万一是正确的,那么这个委托方法的目的是什么?   为什么我不将代码声明为经典方法?它是什么   确切的目的?

由于您提到自己来自Java,因此可以考虑将delegate(){ ... }传递为在某种程度上传递Java中的匿名类。

在Java中,匿名类使您可以同时声明和实例化一个类。它们类似于本地类,只是它们没有名称。如果您只需要使用一次本地类 ,就可以使用它们。

例如,在JDK8之前的Java中,您可以执行以下操作:

btn.setOnAction(new EventHandler<ActionEvent>() {  //<--- implementation
        @Override
        public void handle(ActionEvent event) {
             System.out.println("Hello World!");
        }
  });

或自JDK8起:

btn.setOnAction(e -> System.out.println("Hello World!"));

与C#delegate () {...}中的情况类似,它允许您传递实现,即即时执行某些行为。

使用delegate () {...}是很早以前的常见模式,但是现在您最有可能使用等效于() => { ... }的lambda


您可能会发现以下有趣的帖子: