parameters - parametros - Métodos en conflicto sobrecargados con parámetros opcionales
parametros por defecto c# (3)
Tengo dos métodos sobrecargados, uno con un parámetro opcional.
void foo(string a) { }
void foo(string a, int b = 0) { }
ahora llamo:
foo("abc");
curiosamente se llama la primera sobrecarga. ¿por qué no la segunda sobrecarga con valor opcional puesto a cero?
Para ser sincero, hubiera esperado que el compilador presentara un error, al menos una advertencia para evitar la ejecución involuntaria del método incorrecto.
¿Cuál es la razón de este comportamiento? ¿Por qué el equipo de C # lo definió de esa manera?
Desde MSDN :
Si se considera que dos candidatos son igualmente buenos, la preferencia se dirige a un candidato que no tiene parámetros opcionales para los cuales se omitieron los argumentos en la llamada. Esto es una consecuencia de una preferencia general en la resolución de sobrecarga para los candidatos que tienen menos parámetros.
Imagínense si fuera lo contrario. Usted tenía una aplicación. Tenía un método:
void foo(string a) { }
Everyting funcionó bien. Ahora, desea agregar una sobrecarga más con un parámetro opcional:
void foo(string a, int b = 0) { }
¡Auge! Todas las llamadas a métodos van al nuevo método. Cuando quieras o no. Agregar una sobrecarga de método puede causar llamadas a métodos incorrectos en toda la aplicación.
Desde mi punto de vista, en este caso tendrías muchas más oportunidades de romper tu código (o el de otra persona).
Además, se omitió OptionalAttribute en C # hasta la versión 4.0, pero puede usarlo. Y algunas personas lo usaron en el código C # para admitir ciertos escenarios de interoperabilidad con otros lenguajes, como Visual Basic, o para la interoperabilidad COM. Ahora C # lo usa para parámetros opcionales. Agregar advertencias / errores puede introducir un cambio radical para esas aplicaciones.
Puede haber otras razones, pero esto es lo primero que se me viene a la mente.
Se prefiere una sobrecarga que no requiera ningún parámetro opcional que se complete automáticamente a una que sí lo haga. Sin embargo, no hay tal preferencia entre llenar un argumento automáticamente y completar más de uno, por lo que, por ejemplo, esto causará un error en tiempo de compilación:
void Foo(int x, int y = 0, int z = 0) {}
void Foo(int x, int y = 0) {}
...
Foo(5);
Tenga en cuenta que Foo (5, 5) se resolvería con el segundo método, porque entonces no requiere ningún parámetro opcional para completarse automáticamente.
De la sección 7.5.3.2 de la especificación C # 4:
De lo contrario, si todos los parámetros de MP tienen un argumento correspondiente, mientras que los argumentos predeterminados deben sustituirse por al menos un parámetro opcional en MQ, entonces MP es mejor que MQ.
Creo que en la mayoría de los casos este es el comportamiento que la mayoría de la gente esperaría, para ser honesto. Se pone raro cuando introduces los métodos de la clase base en la mezcla, pero ese siempre ha sido el caso.