0

I have been investigating C# delegates and coming from a python angle I wondered what would happen if I treated a static method as a first-class citizen and just passed it directly as an arg without wrapping in a delegate type.

Surprisingly it seemed to work. However when trying to use the same approach with multicasting, it failed with:

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

My question is what is going on behind the scenes to allow me to pass staticMethod directly as an argument and why won't that same process allow me to multicast the method directly in a similar fashion to what I can achieve using the delegate type?

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
        }
    }
}

possibly its some sort of implicit cast as the following seemed to work:

executeFunc((Func)staticMethod + (Func)staticMethod);
bph
  • 10,728
  • 15
  • 60
  • 135

1 Answers1

2

As you define Func as a delegate, it becomes a System.MultiCastDelegate, for which the operator + is defined. edit: ahum, the compiler turns the addition into a Delegate.Combine, as described here.

your static method is just a normal function, i.e. a method group. And no addition operation is defined for method group types. (what would it do?)

By typing executeFunc((Func)staticMethod + (Func)staticMethod); You are explicitly casting the method group types to delegate types... and the compiler knows what to do again.

edit: By the way, note the existence of System.Action which is the library equal of your Func.

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
  • 1
    `executeFunc((Func)staticMethod + staticMethod);` is Ok. – Roman Ryzhiy Sep 11 '20 at 10:57
  • 1
    @RomanRyzhiy true, but then the first argument is no longer a method group... it has been explicitly cast to a delegate. – JHBonarius Sep 11 '20 at 11:00
  • good point on the System Action delegate, also I can see that a Func delegate is in there as well for when you have args and returns – bph Sep 11 '20 at 11:09