¿Por qué los parámetros opcionales C # 4 definidos en la interfaz no se aplican en la implementación de clase?

Observé que con los parámetros opcionales en C # 4 si especifica un parámetro como opcional en una interfaz, NO es necesario que el parámetro sea opcional en ninguna clase de implementación:

public interface MyInterface { void TestMethod(bool flag = false); } public class MyClass : MyInterface { public void TestMethod(bool flag) { Console.WriteLine(flag); } } 

y por lo tanto:

 var obj = new MyClass(); obj.TestMethod(); // compiler error var obj2 = new MyClass() as MyInterface; obj2.TestMethod(); // prints false 

¿Alguien sabe por qué los parámetros opcionales están diseñados para funcionar de esta manera?

Por un lado, supongo que la capacidad de anular los valores predeterminados especificados en las interfaces es útil, aunque para ser honesto, no estoy seguro de si debería ser capaz de especificar valores predeterminados en la interfaz, ya que eso debería ser una decisión de implementación.

Por otro lado, esta desconexión significa que no siempre se puede utilizar la clase concreta y la interfaz de forma intercambiable. Esto, por supuesto, no sería un problema si el valor predeterminado se especifica en la implementación, pero si expones tu clase concreta como interfaz (usando algún marco IOC para inyectar la clase concreta, por ejemplo) entonces realmente no hay punto que tiene el valor predeterminado, ya que la persona que llama tendrá que proporcionar siempre de todos modos.

ACTUALIZACIÓN: Esta pregunta fue el tema de mi blog el 12 de mayo de 2011. ¡Gracias por la gran pregunta!

Supongamos que tiene una interfaz como la describe y cientos de clases que la implementan. Luego decide hacer que uno de los parámetros de uno de los métodos de la interfaz sea opcional. ¿Está sugiriendo que lo correcto es que el comstackdor obligue al desarrollador a encontrar cada implementación de ese método de interfaz, y que el parámetro sea opcional también?

Supongamos que hicimos eso. Ahora supongamos que el desarrollador no tiene el código fuente para la implementación:


 // in metadata: public class B { public void TestMethod(bool b) {} } 

 // in source code interface MyInterface { void TestMethod(bool b = false); } class D : B, MyInterface {} // Legal because D's base class has a public method // that implements the interface method 

¿Cómo se supone que el autor de D hace que esto funcione? ¿Se les exige en su mundo que llamen al autor de B por teléfono y les piden que les envíen una nueva versión de B que haga que el método tenga un parámetro opcional?

Eso no va a volar. ¿Qué pasa si dos personas llaman al autor de B y uno de ellos quiere que el valor predeterminado sea verdadero y uno de ellos quiere que sea falso? ¿Qué pasa si el autor de B simplemente se niega a seguir el juego?

Quizás en ese caso se les requeriría que diga:

 class D : B, MyInterface { public new void TestMethod(bool b = false) { base.TestMethod(b); } } 

La característica propuesta parece agregar muchos inconvenientes para el progtwigdor sin un aumento correspondiente en el poder representativo. ¿Cuál es el beneficio convincente de esta característica que justifica el mayor costo para el usuario?

Un parámetro opcional solo está etiquetado con un atributo. Este atributo le dice al comstackdor que inserte el valor predeterminado para ese parámetro en el sitio de llamada.

La llamada obj2.TestMethod(); es reemplazado por obj2.TestMethod(false); cuando el código C # se comstack en IL, y no en JIT-time.

Entonces, en cierto modo, siempre es la persona que llama la que proporciona el valor predeterminado con parámetros opcionales. Esto también tiene consecuencias en el control de versiones binarias: si cambia el valor predeterminado pero no vuelve a comstackr el código de llamada, continuará utilizando el valor predeterminado anterior.

Por otro lado, esta desconexión significa que no siempre se puede utilizar la clase concreta y la interfaz de forma intercambiable.

Ya no puede hacer eso si el método de interfaz se implementó de manera explícita .

Porque los parámetros predeterminados se resuelven en tiempo de comstackción, no en tiempo de ejecución. Por lo tanto, los valores predeterminados no pertenecen al objeto al que se llama, sino al tipo de referencia al que se llama.

Los parámetros opcionales son como una sustitución macro de lo que yo entiendo. No son realmente opcionales desde el punto de vista del método. Un artefacto de eso es el comportamiento que ves donde obtienes resultados diferentes si lo lanzas a una interfaz.