Method groups are sets of methods with the same name that the compiler must reduce to a callable delegate type.
Prior to C# 13, natural type resolution could be blocked by overloads that were not actually applicable, such as generic methods with the wrong arity or unsatisfied constraints.
C# 13 improves this by pruning inapplicable overloads earlier so the compiler is more likely to identify a natural type without additional casts.
Code
csharp
// The generic overload cannot be used without type arguments,
// so it is pruned and the method group gets a natural type.
var parse = NumberParser.Parse; // Func<string, int>
static class NumberParser
{
public static int Parse(string text) => int.Parse(text);
public static T Parse<T>(string text) where T : IParsable<T>
=> T.Parse(text, null);
}csharp
// Required an explicit delegate type because the generic overload
// stopped the method group from getting a natural type (error CS8917).
Func<string, int> parse = NumberParser.Parse;
static class NumberParser
{
public static int Parse(string text) => int.Parse(text);
public static T Parse<T>(string text) where T : IParsable<T>
=> T.Parse(text, null);
}Notes
- Candidates are now considered scope by scope, and the search only moves to an outer scope (such as extension methods) when no applicable candidate is found
- Generic methods with the wrong arity, or whose constraints are not satisfied, are removed before the natural type is determined
- Only matters when the method group is not target-typed, for example with
var