2012-03-13 19 views
5

Versión corta: Un argumento con nombre después de un argumento out da un error de compilación, pero no puedo encontrar ningún soporte para este comportamiento en la especificación del lenguaje.Mezcla y parámetros nombrados en C#: ¿Por qué los parámetros de salida también necesitan ser nombrados?

Versión larga:

estoy usando la sobrecarga Enum.TryParse<TEnum> tres parámetros, pero yo preferiría nombrar el parámetro ignoreCase para que mi código más claro, una llamada como:

MyEnum res; 
b = Enum.TryParse<MyEnum>(inputString, true, out res); 

hojas el significado del booleano no es claro (a menos que se conozca este método). Por lo tanto me gustaría usar:

b = Enum.TryParse<MyEnum>(inputString, out res, ignoreCase: true); 

Sin embargo, los informes del compilador como un error:

Named argument 'ignoreCase' specifies a parameter for which a positional argument has already been given

y el IDE resalta el parámetro ignoreCase. La orientación de VS2010 .NET 4 y la VSTA Beta, ya sea con 4 o 4.5, todos dan el mismo resultado. En todos los casos, el nombre del parámetro out elimina el error.

b = Enum.TryParse<MyEnum>(inputString, result: out res, ignoreCase: true); 

He intentado esto a través de una serie de diferentes métodos (incluidos los medicamentos genéricos) evitando , tanto desde el marco y en mi montaje: siempre el mismo resultado: un parámetro out seguido de un parámetro denominado da un error.

puedo ver ninguna razón para este error, y § 7.5.1 listas de argumentos de la C# Language Specification: Versión 4.0 no parece ofrecer ninguna razón para que un out seguido de un parámetro denominado debería dar una error. El texto del error parece apoyar una interpretación como un error: no hay un argumento posicional que pueda ser una coincidencia válida para ignoreCase.

¿Está mal la lectura de la especificación? ¿O es esto un error del compilador?


ahí el consejo en las directrices de diseño de marco para preferir enum parámetros.

Por ejemplo: dado:

private static void TestMethod(int one, float two, out string three) { 
    three = "3333"; 
} 

presente esta llamada también da el mismo error en el parámetro llamado a menos que el parámetro out también se nombra:

TestMethod(1, out aString, two: 1.0f); 

Respuesta

6

parámetros con nombre no permiten usted para "saltar" argumentos posicionales.

Su código se analiza como si pasara los dos primeros argumentos — value y ignoreCase, y luego pasó ignoreCase nuevamente.
No tiene nada que ver con la ness out del parámetro.

Puede solucionarlo pasando el último parámetro también llamado.

+1

Al volver a leer la especificación, puedo ver este enfoque. Es una pena que no use el enfoque de PowerShell: haga coincidir los parámetros nombrados con los argumentos con nombre y luego los parámetros posicionales restantes con los argumentos posicionales restantes. – Richard

3

Cada argumento posicional debe coincidir, si comienza a reorganizar el orden nombrando los argumentos, debe reorganizar todos los argumentos que siguen al que usted nombró.

Así que esta línea de código:

b = Enum.TryParse<MyEnum>(inputString, out res, ignoreCase: true); 

intenta hacer coincidir con out resignoreCase, y luego vienen a lo largo de nombrar ese parámetro nuevo, lo que dispara el compilador de arriba. Es probable que haya otro error al acecho detrás del primero, que out res no concuerda con ignoreCase.

Por lo tanto, si desea "omitir" Ignorar casilla al tratar con argumentos posicionales, también debe nombrar el argumento out res.

Cuestiones relacionadas