使用委托、静态方法和多播将函数作为参数传递

Passing functions as arguments using delegates, static methods and multicasting

我一直在研究 C# 委托并从 python 角度出发,我想知道如果我将静态方法视为第一个 class 公民并直接将其作为 arg 传递会发生什么没有包装在委托类型中。

令人惊讶的是它似乎有效。但是,当尝试对多播使用相同的方法时,它失败了:

[CS0019] Operator '+' cannot be applied to operands of type 'method group' and 'method group'

我的问题是幕后发生了什么,允许我直接将 staticMethod 作为参数传递,为什么同一个进程不允许我以类似的方式直接多播方法我可以使用委托类型来实现吗?

using System;

namespace Delegates
{
    class Program
    {
        public delegate void Func();

        public static void staticMethod()
        {
            Console.WriteLine("In staticMethod()");
        }
        
        public static void executeFunc(Func f)
        {
            f();
        }
        
        static void Main(string[] args)
        {
            Func f = staticMethod;
            
            executeFunc(f);
            
            // why cant' we just pass the static method as a first-class citizen and bypass any delegate creation?'
            executeFunc(staticMethod); // we can - this works
            
            executeFunc(f + f);
            executeFunc(staticMethod + staticMethod); // but this doesn't
        }
    }
}

可能是某种隐式转换,如下所示:

executeFunc((Func)staticMethod + (Func)staticMethod);

当您将 Func 定义为委托时,它会变成 System.MultiCastDelegate,并为其定义运算符 +。 编辑:嗯,编译器将加法转换为 Delegate.Combine,如 .

所述

您的静态方法只是一个普通函数,即 method group。并且没有为 method group 类型定义加法运算。 (它会做什么?)

通过键入 executeFunc((Func)staticMethod + (Func)staticMethod);,您可以显式地将方法组类型转换为委托类型...并且编译器知道该怎么做。

编辑:顺便说一下,请注意 System.Action 的存在,它与您的 Func 相同。