C#中的方法组是什么?

And*_*nea 336 .net c# method-group

在以下情况下,我经常遇到一个错误,例如"无法从'方法组'转换为'字符串'"

var list = new List<string>();
// ... snip
list.Add(someObject.ToString);
Run Code Online (Sandbox Code Playgroud)

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

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

但是我想知道什么是方法组.谷歌也不是MSDN的帮助.

Mar*_*ell 313

方法组是一个名称的一套方法(可能是只有一个) -即理论上的ToString方法可以有多个重载(加任何扩展方法)ToString(),ToString(string format)等-因此ToString本身是一个"方法组".

它通常可以通过使用重载解析将方法组转换为(类型化)委托 - 但不能转换为字符串等; 它没有意义.

再次添加括号后; 超载分辨率开始,您已明确地识别出方法调用.

  • 它纯粹是"我知道方法名称是什么,但我不知道签名"的编译器术语; 它在运行时没有存在.AFAIK,在委托构建期间,唯一使用方法组**(没有括号等). (29认同)
  • ECMA334v4§14.1:方法组可用于invocation-expression(第14.5.5节),在delegate-creation-expression(第14.5.10.3节)中使用,或隐式转换为兼容的委托类型.在任何其他上下文中,分类为方法组的表达式会导致编译时错误. (19认同)
  • 方法组的典型用途是什么?由于(我理解)它具有相同的名称,参数计数和/或类型将有所不同.因此,您无法使用该组从方法组中调用多个方法. (6认同)

小智 156

此外,如果您使用LINQ,您显然可以做类似的事情myList.Select(methodGroup).

所以,例如,我有:

private string DoSomethingToMyString(string input)
{
    // blah
}
Run Code Online (Sandbox Code Playgroud)

而不是明确地声明要使用的变量,如下所示:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(str => DoSomethingToMyString(str));
}
Run Code Online (Sandbox Code Playgroud)

我可以省略var的名称:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(DoSomethingToMyString);
}
Run Code Online (Sandbox Code Playgroud)

  • ReSharper建议是我搜索方法组的原因.这就是ReSharper最终对我的一个linq表达式所做的事情. (109认同)
  • @a_hardin:ReSharper FTW!感谢Resharper,我学到了很多关于LINQ的知识. (49认同)
  • 让我想起`return flag == true?true:false`(facepalm). (14认同)
  • 编译器什么都不优化.使用ILDASM,您会看到显式版本创建了一个匿名方法(lambda实现)并将其传递给Select().隐式版本直接传递DoSomethingToMyString. (6认同)
  • "更明确"的版本只是制作一个基本无用的包装器方法.匿名包装器方法和DoSomethingToMyString都接受一个字符串并返回一个字符串."str => [...](str)"字符只是编译器希望优化掉的东西. (3认同)

Jac*_*ack 22

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

委托签名从组中选择1个方法.

此示例选择ToString()带有字符串参数的重载:

Func<string,string> fn = 123.ToString;
Console.WriteLine(fn("00000000"));
Run Code Online (Sandbox Code Playgroud)

此示例选择ToString()不带参数的重载:

Func<string> fn = 123.ToString;
Console.WriteLine(fn());
Run Code Online (Sandbox Code Playgroud)


osc*_*kuo 19

MSDN搜索的第一个结果是:

方法组标识要调用的一个方法或从中选择要调用的特定方法的重载方法集

我的理解是,基本上因为当你刚写的时候someInteger.ToString,它可能会引用:

Int32.ToString(IFormatProvider) 
Run Code Online (Sandbox Code Playgroud)

或者它可以参考:

Int32.ToString()
Run Code Online (Sandbox Code Playgroud)

所以它被称为方法组.


180*_*ION 17

ToString函数有许多重载 - 方法组将是由该函数的所有不同重载组成的组.

  • 是的,重点是方法组是编译时构造。编译器根据使用消息组的上下文选择一种方法重载。例如:您不能写“ var x = Foo;” (其中Foo是方法组),即使只有一个重载,编译器也会拒绝此操作。 (2认同)