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

问题描述

我一直在研究C#委托,并且从python的角度出发,我想知道如果将静态方法视为一等公民并将其直接作为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为其定义了运算符+。 编辑:ahum,编译器将加法转换成Delegate.Combine,如here所述。

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

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

编辑:顺便说一下,请注意System.Action的存在,它等于您的Func的库。