The Evolution of Method Group Conversion

What the heck is a method group? The formal definition from section 14.1 of ECMA 334 is:

A method group, which is a set of overloaded methods resulting from a member lookup (§14.3). A method group can have an associated instance expression. When an instance method is invoked, the result of evaluating the instance expression becomes the instance represented by this (§14.5.7). A method group can be used in an invocation-expression (§14.5.5), used in a delegate-creation-expression (§14.5.10.3), or implicitly converted to a compatible delegate type. In any other context, an expression classified as a method group causes a compile-time error.


Jon Skeet wrote a definition that’s a bit more clear;

So in other words, when you write something like: EventHandler handler = MyMethod; then “MyMethod” refers to a method group. There could be multiple methods with the same name, but different signatures. The method group conversion creates a delegate calling the appropriate actual method. All the methods in the group are available in the same context – they could belong to different classes due to inheritance, or there could be extension methods available – but they’re related in terms of the context the member lookup is occurring in.

Source

Overload resolution determines the actual one to call. Likely you’ve been using method groups, but didn’t know they had a formal name. In the code below, Form1_Closing refers to a method group.

this.Closing += Form1_Closing;

Hopefully this explains what is a method group. Method group conversion is actually easier to understand. It’s simply converting the method group to a delegate type with a matching signature. This part of C# has enjoyed a nifty evolution from C#1.0 to C#3.0. Which is illustrated in the code below:

using System;
 
namespace GroupMethodPlayground
{
  public delegate void OrderReceived(int orderId);
 
  public class Program
  {
    static void Main()
    {
      // Add a method group to the delegate - C# 1.0
      OrderReceived newOrder = new OrderReceived(SendOrderConfirmationMessage);
 
      // Add using implicit method group conversion - C# 2.0
      newOrder += SendOrderConfirmationMessage;
 
      // Add as an anonymous method - C# 2.0
      newOrder += delegate(int orderId) { Console.WriteLine("Sending confirmation message for order {0} (anonymous delegate)", orderId); };
 
      // Add as a lamba expression - C# 3.0
      newOrder += orderId => Console.WriteLine("Sending confirmation message for order {0} (lamba)", orderId);
 
      newOrder(10509);
 
      Console.ReadKey();
    }
 
    private static void SendOrderConfirmationMessage(int orderId)
    {
      Console.WriteLine("Sending confirmation message for order {0}", orderId);
    }
  }
}

Leave a Reply