2008-09-02 28 views
10

¿Es verdad que la única forma de manejar los argumentos de las funciones predeterminadas es a través de la sobrecarga de funciones?¿Sobrecargar es la única forma de tener argumentos de funciones por defecto en C#?

Por ejemplo, en PHP que puedo hacer esto:

function foo($x, $y=0) 
{ 
} 

¿Sería la mejor manera de manejar la situación en C# ser esto?

void foo(int x) 
{ 
    foo(x, 0); 
} 

void foo(int x, int y) 
{ 
} 

Example lifted from here

Editar

hizo el ejemplo de C# en efectivo de C# (Gracias Blair Conrad)

+2

¿No ha cambiado en C# 4.0? Parece que ahora puede usar argumentos con nombre con valores predeterminados. Ver http://msdn.microsoft.com/en-us/library/dd264739.aspx La mayoría de las respuestas (desde 2008) parecen obsoletas y ahora son incorrectas. – Keyo

+0

Sí, ahora está disponible para C#. –

Respuesta

5

Sí, eso sería mejor , excepto que omitiría el $ s en los nombres de los parámetros, como han señalado otros. Para aquellos interesados ​​en la razón de ser de la falta de valores de parámetros predeterminados, vea la explicación de @Giovanni Galbo.

2

Los argumentos predeterminados son parte de C++, pero a partir de C# 3.5 los argumentos predeterminados aún no son compatibles-- tendrá que sobrecargar. Han estado disponibles en VB.Net desde 1.0.

0

Sí.

O currying.

O resuma en una clase y use los valores predeterminados allí.

0

No, AFAIK C# no admite la anulación, y sí, esa es la forma recomendada de lograr el mismo efecto.

20

sólo para satisfacer alguna curiosidad:

De Why doesn't C# support default parameters?:

En lenguajes como C++, un valor por defecto puede ser incluido como parte de la declaración de método:

Proceso de vacío (Empleado empleado, bool bonus = falso)

Este método se puede llamar con:

a.Process (employee, true);

o

a.Proceso (empleado);

en el segundo caso, la bonificación del parámetro se establece en falsa.

C# no tiene esta característica.

Una razón por la que no tenemos esta función está relacionada con una implementación específica de la función. En el mundo de C++, cuando el usuario escribe:

a.Proceso (empleado);

el compilador genera

a.process (empleado, false);

En otras palabras, el compilador toma el valor predeterminado que se especifica en el prototipo del método y lo coloca en la llamada al método; es como si el usuario hubiera escrito 'falso' como el segundo parámetro. No hay forma de cambiar ese valor predeterminado sin obligar al usuario de la clase a recompilar, lo cual es desafortunado.

El modelo de sobrecarga funciona mejor a este respecto. El autor del marco simplemente define dos métodos separados, y el de un solo parámetro llama al método de dos parámetros. Esto mantiene el valor predeterminado en el marco, donde se puede modificar si es necesario.

Sería posible para un compilador tomar algo como la definición de C++ y producir las sobrecargas, pero hay algunos problemas con ese enfoque.

El primero es que la correlación entre el código que el usuario escribe y el código que genera el compilador es menos obvio. Por lo general, tratamos de limitar la magia cuando es posible, ya que hace que sea más difícil para los programadores. El segundo problema tiene que ver con cosas como XML doc comments e intellisense. El compilador debería tener reglas especiales sobre cómo generar comentarios de documentación para los métodos sobrecargados, y intellisense debería tener inteligencia para colapsar los métodos sobrecargados en un único método.

Escribir sobrecargas es un poco menos conveniente, pero creemos que es una solución aceptable.

3

En cuanto a la excerpt from the c# faq:

La mayor parte de los problemas enumerados en el mismo se resolvieron por VB.Net (específicamente las cuestiones de IntelliSense y xml comentarios), que significa que son muy herrings-- roja existen códigos disponibles al equipo de C# que resolverá el problema.

Otra razón tiene que ver con obligar a un usuario de una clase a volver a compilar, pero eso también es un misterio. Si cambia un valor predeterminado en su clase de infraestructura y el usuario no no tiene que volver a compilar, se arriesga al usuario sin saber que el valor predeterminado cambió. Ahora tiene un error potencial en el código que no aparece hasta el tiempo de ejecución. En otras palabras, la alternativa de sobrecargar la función es al menos tan mala. Por supuesto, esto también presupone una implementación específica de la función, pero es la implementación sugerida en la pregunta frecuente.

Por lo tanto, tiene que ponderar el motivo restante ("intentar limitar la magia") frente al hecho (que reconocen) de que escribir las sobrecargas es "un poco menos conveniente". Personalmente, digo poner la función y dejar que el programador decida si usarla o no.

0

¿no hace esto el trabajo?

void foo(int x):this(x, 0){} 

void foo(int x, int y){ 
// code here 
} 
Cuestiones relacionadas