我经常遇到一个错误,如“无法从'方法组'转换为'字符串'”在这种情况下:

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

当然,在最后一行中有一个拼写错误,因为我忘记了ToString之后的调用括号。正确的形式应该是:

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

然而,我开始想知道什么是方法组。谷歌没有多大帮助,也没有MSDN。


方法组是一组方法的名称(可能只有一个)-即理论上ToString方法可能有多个重载(加上任何扩展方法):ToString(), ToString(字符串格式)等-因此ToString本身是一个“方法组”。

它通常可以通过重载解析将方法组转换为(类型化)委托,但不能转换为字符串等;这没有道理。

一旦你加了括号,再加一次;重载解析开始生效,您已经明确地标识了一个方法调用。


你的MSDN搜索的第一个结果是:

方法组标识该方法 的集合 的重载方法 选择要调用的特定方法

我的理解是,当你写someInteger的时候。ToString,它可以指:

Int32.ToString(IFormatProvider) 

也可以指:

Int32.ToString()

所以它被称为方法组。


ToString函数有许多重载——方法组是由该函数的所有不同重载组成的组。


同样,如果你正在使用LINQ,你显然可以做一些类似myList.Select(methodGroup)的事情。

例如,我有:

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

而不是像这样显式地声明变量:

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

我可以省略var的名字:

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

可以将方法组强制转换为委托。

委托签名从组中选择一个方法。

下面的例子选择ToString()重载,它接受一个字符串参数:

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

下面的例子选择了ToString()重载,它不带参数:

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