2009-05-20 5 views
299

me he encontrado a menudo un error como "no se puede convertir de 'grupo Método' a 'cadena'" en casos como:¿Qué es un grupo de métodos en C#?

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

Por supuesto que había un error tipográfico en la última línea porque se me olvidó los paréntesis de invocación después de ToString. La forma correcta sería:

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

Sin embargo, llegué a preguntarme qué es un grupo de métodos. Google no es de mucha ayuda ni MSDN.

+52

Sección 7.1 de la especificación de C# 3.0 define método" grupo". –

+1

He leído este error ahora como * te perdiste los corchetes al llamar a un método *. – niico

Respuesta

279

Un grupo método es el nombre para un conjunto de métodos(que podría ser sólo uno) - es decir, en teoría el método ToString puede tener múltiples sobrecargas (además de cualquiera de los métodos de extensión): ToString(), ToString(string format), etc - por lo tanto ToString por sí mismo es un "grupo de métodos".

Por lo general, puede convertir un grupo de métodos en un delegado (tipeado) mediante la resolución de sobrecarga, pero no a una cadena, etc .; no tiene sentido.

Una vez que agregue paréntesis, nuevamente; la resolución de sobrecarga entra en acción y usted ha identificado inequívocamente una llamada a un método.

+6

¿Cuáles serían los usos típicos de un grupo de métodos? Dado que (por lo que entiendo) tiene el mismo nombre, el número de parámetros y/o tipos serán diferentes. Por lo tanto, no puede invocar más de un método del grupo de métodos que usa el grupo. –

+23

Es simplemente un término de compilación para "sé cuál es el nombre del método, pero no sé la firma"; no tiene existencia en tiempo de ejecución. AFAIK, el único uso de un grupo de métodos * por sí solo * (sin corchetes, etc.) es durante la construcción del delegado. –

+16

ECMA 334v4 §14.1: Un grupo de métodos se puede usar en una expresión de invocación (§14.5.5), utilizado en una expresión de creación de delegados (§14.5.10.3), o convertido implícitamente a un tipo de delegado compatible. En cualquier otro contexto, una expresión clasificada como un grupo de métodos causa un error en tiempo de compilación. –

16

El primer resultado en su búsqueda de MSDN dijo:

El grupo método identifica el método para invocar o el conjunto de métodos sobrecargados desde la que elegir un método específico para invocar

mi entendimiento es que, básicamente, cuando solo escribe someInteger.ToString, puede referirse a:

Int32.ToString(IFormatProvider) 

o puede hacer referencia a:

Int32.ToString() 

por lo que se llama un grupo método.

15

La función ToString tiene muchas sobrecargas; el grupo de métodos sería el grupo formado por todas las sobrecargas diferentes para esa función.

+1

Sí, y el hecho es que un grupo de métodos es una construcción en tiempo de compilación. El compilador elige una sobrecarga de método de acuerdo con el contexto donde se utiliza el grupo de mensajes. Por ejemplo: no puede escribir "var x = Foo;" (donde Foo es un grupo de métodos), el compilador rechaza esto incluso si solo hay una sobrecarga. – Rolf

140

Además, si está utilizando LINQ, aparentemente puede hacer algo como myList.Select(methodGroup).

Así, por ejemplo, que tengo:

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

En lugar de establecer explícitamente la variable que se utilizará como esto:

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

que sólo puede omitir el nombre de la variable:

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

Una recomendación de ReSharper es lo que me llevó a buscar el grupo de métodos. Esto es lo que ReSharper terminó haciendo a una de mis expresiones linq. –

+42

@a_hardin: ¡ReSharper FTW! Aprendí mucho sobre LINQ gracias a Resharper. –

+1

¿Hay algún inconveniente en esto? ¿Por qué un "no" querría hacerlo de esta manera? – JCisar

17

Puede convertir un grupo de métodos en un delegado.

La firma del delegado selecciona 1 método fuera del grupo.

Este ejemplo recoge la sobrecarga ToString() que tiene un parámetro de cadena:

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

Este ejemplo recoge la sobrecarga ToString() que no toma ningún parámetro:

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