What is a method group in C?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A method group in C# is the name of a method referenced without parentheses. When you write Console.WriteLine instead of Console.WriteLine("hello"), you are referring to the method group: the entire set of overloads that share that name. The compiler uses the surrounding context (a delegate type, a lambda target, or a LINQ method parameter) to pick the specific overload from the group.
Method groups are central to how C# handles delegates, event subscriptions, and LINQ. Understanding them clears up a whole category of compiler errors and helps you write more concise code.
What Exactly Is a Method Group
A method group is not a value you can store in a variable directly. It is an expression type that the compiler resolves to a specific method when it has enough context. The context is almost always a delegate signature.
Consider a class with overloaded methods:
The identifier MathOps.Add is a method group containing three overloads. You cannot assign MathOps.Add to var because the compiler does not know which overload you mean. But you can assign it to a delegate type:
The compiler performs method group conversion: it matches the delegate signature to the correct overload and produces a delegate instance pointing to that method.
Method Group Conversion
Method group conversion is the implicit process by which the compiler turns a method group into a delegate. It follows the same overload resolution rules as a normal method call, except the "arguments" come from the delegate's parameter types rather than from actual values.
The conversion fails at compile time if no overload matches the delegate signature, or if more than one overload matches ambiguously.
Method Groups vs. Lambda Expressions
Before C# 2.0 introduced anonymous methods and C# 3.0 introduced lambdas, method groups were the primary way to create delegate instances. Today, you often see both styles side by side:
Both produce the same result, but the method group syntax is shorter and avoids an extra allocation in some cases. The compiler can sometimes cache the delegate created from a method group, while a lambda that captures variables always allocates.
When to Prefer Each Style
| Scenario | Recommended | Reason |
| Event subscription to an existing method | Method group | Shorter, no wrapper delegate |
| Inline logic with no existing method | Lambda | No need to define a named method |
| LINQ projection with a simple static method | Method group | list.Select(int.Parse) reads cleanly |
| Logic that captures local variables | Lambda | Method groups cannot capture locals |
| Unsubscribing from events | Method group | Same method reference enables - = removal |
Method Groups in LINQ
Method groups shine in LINQ chains where a static method already does what you need:
Both produce the same result. The method group version is more concise and signals to the reader that no transformation beyond int.Parse is happening.
Another common example:
Notice that method groups work best when the method signature matches the delegate parameter exactly. If you need to negate, transform, or add arguments, a lambda is required.
Method Groups and Event Handling
Event subscription is one of the most common uses of method groups:
Using method groups for both += and -= ensures the delegate references match, allowing proper unsubscription. If you subscribe with a lambda, unsubscribing is unreliable because each lambda creates a different delegate instance.
The "Cannot convert method group to non-delegate type" Error
One of the most common compiler errors involving method groups occurs when you write a method name without parentheses in a context that expects a value:
This error means you are referencing the method group when you meant to call the method. The fix is almost always adding ().
The reverse error occurs when you write parentheses where a method group is expected:
Natural Type for Method Groups (C# 11+)
Starting with C# 11, method groups can have a "natural type" in certain contexts. This means the compiler can infer the delegate type without you specifying it explicitly:
In earlier versions, this would fail with "cannot assign method group to implicitly typed variable." The natural type feature makes method groups more convenient in quick prototyping and scripting scenarios.
Comparison: Method Groups, Delegates, and Lambdas
| Concept | What It Is | Example |
| Method group | A reference to one or more overloads by name | Console.WriteLine |
| Delegate | A type-safe function pointer type | Action<string>, Func<int, bool> |
| Delegate instance | An object pointing to a specific method | new Action<string>(Console.WriteLine) |
| Lambda expression | An anonymous function defined inline | x => x > 0 |
| Method group conversion | Implicit conversion from method group to delegate | Action<string> a = Console.WriteLine; |
Common Pitfalls
- Forgetting parentheses when calling a method: Writing
obj.Methodinstead ofobj.Method()produces a method group expression, not the return value. The compiler error message mentions "method group" which confuses developers unfamiliar with the term. - Using method groups with overloads and ambiguous delegates: If multiple overloads could match the delegate type, the compiler reports an ambiguity error. Resolve it by casting or using a lambda that explicitly selects the overload.
- Unsubscribing events with lambdas instead of method groups: Subscribing with
event += (s, e) => Handle(s, e)and then tryingevent -= (s, e) => Handle(s, e)does not work because the two lambdas are different delegate instances. Use a method group or store the delegate in a field. - Assuming method groups capture state: Method groups on instance methods do capture
this, but they cannot capture local variables. If you need closure semantics, use a lambda. - Ignoring return type mismatches: A method group conversion checks both parameter types and return type.
Func<int>will not accept a method group for avoidmethod, even if the parameters match.
Summary
- A method group is a method name referenced without parentheses, representing all overloads of that method.
- The compiler resolves which overload to use based on the target delegate type through method group conversion.
- Method groups provide concise syntax for event subscriptions, LINQ projections, and delegate assignments.
- Prefer method groups over lambdas when an existing method already matches the required signature, and use lambdas when you need inline logic or variable capture.
- The most common method group error is forgetting parentheses when you meant to call the method, or including parentheses when you meant to pass the method as a delegate.
- C# 11 added natural type inference for method groups, making
var action = Console.WriteLine;valid.

