2010-11-27 31 views
49

En C# 4, ¿hay una buena manera de tener un parámetro de salida opcional?Parámetros de salida opcionales

+0

No encuentra ningún valor para dicha función. Si alguna vez escuchaste las sesiones de compiladores de C# en PDC, verás que cada cambio tiene un significado. –

+29

No estoy de acuerdo con que no haya ningún valor en esta característica. Si un método tiene algo de lógica en él, al igual que devolver datos a través de parámetros de salida, quiero poder invocar esta lógica, simplemente no necesito la salida ... – Alex

+1

Uso Int32.TryParse() para ver si la cadena dada se puede analizar en un número y, si puede, a veces eso es todo lo que me importa. Entonces Jitbit tiene razón. –

Respuesta

5

Para que sea "opcional", en el sentido de que no es necesario asignar un valor en el método, se puede utilizar ref.

+3

Un parámetro 'ref' es un caso de uso muy diferente. Un parámetro opcional pasa en un valor específico si la persona que llama no especifica uno: con un parámetro ref, la persona que llama siempre especifica un valor, si sienten que lo han especificado o no. El 'ref' siempre apunta a una ubicación de memoria válida, y una ubicación de memoria válida siempre contiene _something_. En el mejor de los casos, esto es solo un valor mágico sin el beneficio de una especificación predeterminada que dice "el valor predeterminado es X". – danwyand

+2

Sí, esta respuesta no es un juicio de diseño, por lo que agregué el calificador "en el sentido de que". – codekaizen

48

No realmente, aunque siempre se puede sobrecargar el método con otro que no toma el parámetro de salida.

+3

cualquier idea de cómo manejar el parámetro opcional de forma más elegante que '{string dummy; devuelve Foo (fuera del maniquí); } 'en la sobrecarga que no toma el parámetro de salida? –

+2

@Louis: ¡No, eso es probablemente lo que habría hecho! – Cameron

+0

Eso es mucho código de placa de caldera adicional. – Brain2000

2
private object[] Func(); 

asigne tantas salidas opcionales como desee a la matriz de objetos de retorno y luego ¡úselos! pero si quieres decir algo como salida opcional

private void Func(out int optional1, out string optional2) 

y luego se llama algo así como

Func(out i); 

entonces la respuesta es no, puedes. también C# y .NET Framework tiene muchas estructuras de datos que son muy flexibles como List y Array y puede usarlas como un parámetro de salida o como un tipo de retorno para que no haya necesidad de implementar una forma de tener parámetros de salida opcionales.

7

Decorar los parámetros con OptionalAttribute tampoco funciona. Para ampliar la muestra anterior, obtendrá algo como:

private void Func(
    [Optional] out int optional1, 
    [Optional] out string optional2) 
{ /* ... */ } 

Tenga en cuenta que lo anterior se compilará (quizás por desgracia). Sin embargo, intentar compilar:

Func(out i); 

fallará si no se proporciona explícitamente una sobrecarga con una firma de un solo parámetro.

Para (teóricamente) hacer que el trabajo anterior sea un problema importante. Cuando se llama a un método con un parámetro opcional omitido, se crea un marco de pila que contiene los valores de todos los parámetros y los valores faltantes simplemente se rellenan con los valores predeterminados especificados.

Sin embargo, un parámetro de "salida" es una referencia, no un valor. Si ese parámetro es opcional y no se proporciona, ¿a qué variable se referiría? El compilador aún necesita imponer el requisito de que el parámetro "salir" se complete antes de cualquier devolución normal del método, ya que el compilador no sabe a priori qué parámetros (si los hay) opcionales son especificados por la persona que llama. Esto significa que se debería pasar una referencia a la variable ficticia en algún lugar, por lo que el método tiene algo que llenar. Administrar este espacio variable ficticio crearía un desagradable dolor de cabeza para el escritor del compilador. No estoy diciendo que sería imposible determinar los detalles de cómo funcionaría esto, pero las implicaciones arquitectónicas son tan grandes que Microsoft pasó esta característica de manera comprensible.

0
public class Dummy<T> 
{ 
    public T Value; 
} 

A continuación, utilice functionDoSomething(out new Dummy<int>().Value, donde int podría ser cualquier tipo.

Cuestiones relacionadas