407

I have often encountered an error such as "cannot convert from 'method group' to 'string'" in cases like:

var list = new List<string>();
// ... snip
list.Add(someObject.ToString);

of course there was a typo in the last line because I forgot the invocation parentheses after ToString. The correct form would be:

var list = new List<string>();
// ... snip
list.Add(someObject.ToString()); // <- notice the parentheses

However I came to wonder what is a method group. Google isn't much of a help nor MSDN.

Andrei Rînea
  • 20,288
  • 17
  • 117
  • 166

5 Answers5

383

A method group is the name for a set of methods (that might be just one) - i.e. in theory the ToString method may have multiple overloads (plus any extension methods): ToString(), ToString(string format), etc - hence ToString by itself is a "method group".

It can usually convert a method group to a (typed) delegate by using overload resolution - but not to a string etc; it doesn't make sense.

Once you add parentheses, again; overload resolution kicks in and you have unambiguously identified a method call.

ErikE
  • 48,881
  • 23
  • 151
  • 196
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 7
    What would be typical uses of a method group? Since (so I understand) it has the same name the parameter count and/or types will differ. So you cannot invoke more than one method from the method group using the group. – Andrei Rînea May 20 '09 at 10:55
  • 37
    It is purely a compiler term for "I know what the method name is, but I don't know the signature"; it has no existence at runtime. AFAIK, the only use of a method-group *by itself* (no brackets etc) is during delegate construction. – Marc Gravell May 20 '09 at 11:00
  • 21
    ECMA 334v4 §14.1: 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. – Marc Gravell May 20 '09 at 11:02
  • 1
    Covariance and contravariance support for method groups allows for matching method signatures with delegate types. This enables you to assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept parameters that have less derived types (contravariance) than that specified by the delegate type. For more information, see Variance in Delegates (C#) and Using Variance in Delegates (C#). – SKARVA Bodavula Nov 24 '17 at 12:27
  • 100% of the time when I get this error, I forgot the brackets on the method call cause I thought it was a property. An error like "did you forget the ()" would actually be useful 99% of the time lol – niico Sep 05 '21 at 10:21
189

Also, if you are using LINQ, you can apparently do something like myList.Select(methodGroup).

So, for example, I have:

private string DoSomethingToMyString(string input)
{
    // blah
}

Instead of explicitly stating the variable to be used like this:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(str => DoSomethingToMyString(str));
}

I can just omit the name of the var:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(DoSomethingToMyString);
}
anar khalilov
  • 16,993
  • 9
  • 47
  • 62
Kaeles
  • 1,891
  • 1
  • 11
  • 2
  • 127
    A ReSharper recommendation is what led me to search for method group. This is what ReSharper ended up doing to one of my linq expressions. – a_hardin Nov 11 '10 at 13:59
  • 55
    @a_hardin: ReSharper FTW! I learned a lot about LINQ thanks to Resharper. – Jason Down Jan 06 '12 at 04:35
  • 3
    The "more explicit" version is only making an essentially useless wrapper method. The anonymous wrapper method and DoSomethingToMyString both take a string and return a string. The "str => [...](str)" characters are just cruft which the compiler hopefully optimizes away. – Grault Mar 18 '13 at 07:32
  • 7
    The compiler optimizes nothing. Using ILDASM, you see that the explicit version creates a anonymous method (the lambda implementation) and passes it to Select(). The implicit version passes DoSomethingToMyString directly. – Rolf Nov 14 '14 at 15:01
  • 18
    Reminds me of `return flag == true ? true : false` (facepalm). – ErikE Feb 20 '15 at 02:46
  • 1
    According to this test (http://vibrantcode.com/2013/02/19/lambdas-vs-method-groups/) lambda appears to be faster, even though it creates an extra wrapper method. – rothschild86 Mar 30 '17 at 13:42
  • The [relevant overload](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select#System_Linq_Enumerable_Select__2_System_Collections_Generic_IEnumerable___0__System_Func___0___1__) of `Select` wants a delegate of type `Func` for its `selector` argument. This is exactly what method groups can be used for: Conversion into (compatible) delegate types. – Jeppe Stig Nielsen Jul 28 '19 at 09:46
  • @ErikE, updated link: [Wayback Archive - vibrantcode.com/2013/02/19/lambdas-vs-method-groups](https://web.archive.org/web/20190301033146/http://vibrantcode.com/2013/02/19/lambdas-vs-method-groups/) – phooBarred May 17 '23 at 22:18
38

You can cast a method group into a delegate.

The delegate signature selects 1 method out of the group.

This example picks the ToString() overload which takes a string parameter:

Func<string,string> fn = 123.ToString;
Console.WriteLine(fn("00000000"));

This example picks the ToString() overload which takes no parameters:

Func<string> fn = 123.ToString;
Console.WriteLine(fn);
Soleil
  • 6,404
  • 5
  • 41
  • 61
Jack
  • 4,684
  • 2
  • 29
  • 22
22

The first result in your MSDN search said:

The method group identifies the one method to invoke or the set of overloaded methods from which to choose a specific method to invoke

my understanding is that basically because when you just write someInteger.ToString, it may refer to:

Int32.ToString(IFormatProvider) 

or it can refer to:

Int32.ToString()

so it is called a method group.

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
oscarkuo
  • 10,431
  • 6
  • 49
  • 62
20

The ToString function has many overloads - the method group would be the group consisting of all the different overloads for that function.

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
  • 2
    Yes, and the point is that a method group is a compile-time construct. The compiler chooses one method overload according to the context where the message group is used. For example: you cannot write "var x = Foo;" (where Foo is a method group), the compiler rejects this even if there is only one overload. – Rolf Nov 14 '14 at 15:06