2009-04-02 9 views
5

Los siguientes ejemplos de impresión de código:¿Cómo funciona exactamente la palabra clave 'params'?

T 
T[] 
T[] 

Mientras dos primeras líneas son como se esperaba, ¿por qué compilador seleccionada gama parámetro para una matriz regular?

public class A 
{ 
    public void Print<T>(T t) 
    { 
     Console.WriteLine("T"); 
    } 

    public void Print<T>(params T[] t) 
    { 
     Console.WriteLine("T[]"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     A a = new A(); 
     a.Print("string"); 
     a.Print("string","string"); 
     a.Print(new string[] {"a","b"}); 
    } 
} 
+1

Usted haga muchas preguntas interesantes –

Respuesta

10

Bajo el capó

a.Print("string","string"); 

es sólo azúcar sintáctica para

a.Print(new string[]{"string","string"}); 

EDIT: Como he dicho, la palabra clave params única automagicamente crea la matriz para usted, usted le dice al compilador : cualquiera acepta una matriz de T directamente o usa los parámetros de entrada X para construir esa matriz.

+0

Vuelva a leer la pregunta. – strager

+0

@strager: Deberías leer la pregunta. arul tiene razón. – Samuel

+0

Bueno, tal vez estoy totalmente mal entendiendo algo aquí. ¿Puedes elaborar tu respuesta un poco? – strager

0

Params le permite pasar varios objetos del mismo tipo. es una forma de acceso directo de pasar matriz

+0

Como otros escriben, no existe una matriz params, ni hay ninguna 'asignación a una matriz params'. Es solo una matriz y la palabra clave params permite escribir una sintaxis más compacta. –

+0

Perdón por la palabra incorrecta ... –

0

Creo que esto en realidad tiene más que ver con la inferencia de tipo que con la palabra clave params. El motor de inferencia asume en la tercera línea que el tipo de T es una cadena [] y, por lo tanto, lo pasa al primer método.

intento Console.WriteLine (typeof (T)) si no me cree

+0

El primer método imprime solo 'T', entonces estás equivocado. – Prankster

+0

no, no estás entendiendo lo que digo. El primero, el motor de inferencia mapea T para escribir una cadena, el tercero asigna T para escribir una cadena []. Simplemente reemplace las salidas de la consola con Console.WriteLine (typeof (T)); y verá –

+0

@George, es incorrecto: T será cadena en los tres casos. – LukeH

0

al tener la palabra clave params, el compilador hará un poco de traducción de la declaración de la función formal, así como la llamada de función real.

declaración de la función formal:

Bajo el capó, el IL serán traducidos a esencialmente el mismo que

public void Print<T>(T[] array); 

excepción, al compilar, el llamada a la función se comprobará la traducción de sintaxis . Significado,

a.Print("string1", "string2"); 

Se convierte el mismo código IL como

a.Print(new string[]{"string1", "string2"}); 

Esa es la razón por la línea 2 y 3 son la misma salida, porque bajo el capó, consiguieron convierten a la misma IL.

Pregunta sobre por qué la línea 3 no se imprime "T" es porque el compilador .NET siempre intentará encontrar la mejor coincidencia sobrecargada, por lo que tanto la línea 2 como la 3 llamaron a la versión T []

0

Exactamente como dijo arul. Si abre el proyecto en el reflector, verá lo siguiente:

a.Print<string>(new string[] { "string", "string" }); 
5

Es además de lo que otros han dicho, los parametros palabra clave también causa una ParamArrayAttribute a la generada por parámetro de matriz. Entonces, esto ...

public void Print<T>(params T[] t) { } 

Es generado por el compilador como ...

public void Print<T>([ParamArray] T[] t); { } 

Es ese atributo que indica al compilador y el IDE que el método puede ser llamado usando la sintaxis más simple ...

a.Print("string", "string"); 

en lugar de ...

a.Print(new string[] { "string", "string" }); 
Cuestiones relacionadas