parametros parametro parameter opcionales opcional method define c# interface c#-4.0 optional-parameters

c# - parametro - Parámetros opcionales para interfaces



parametro opcional c# (6)

Usando c # 4.0 - construyendo una interfaz y una clase que implementa la interfaz. Quiero declarar un parámetro opcional en la interfaz y hacer que se refleje en la clase. Entonces, tengo lo siguiente:

public interface IFoo { void Bar(int i, int j=0); } public class Foo { void Bar(int i, int j=0) { // do stuff } }

Esto compila, pero no se ve bien. La interfaz debe tener los parámetros opcionales, porque de lo contrario no se refleja correctamente en la firma del método de interfaz.

¿Debo omitir el parámetro opcional y simplemente usar un tipo que admite nulos? ¿O funcionará como está previsto sin efectos secundarios o consecuencias?


Podría considerar la alternativa de los parámetros opcionales:

public interface IFoo { void Bar(int i, int j); } public static class FooOptionalExtensions { public static void Bar(this IFoo foo, int i) { foo.Bar(i, 0); } }

Si no le gusta el aspecto de una nueva función de idioma, no tiene que usarla.


Mira a un lado, eso hará exactamente lo que parece que quieres lograr.


¿Qué tal algo así?

public interface IFoo { void Bar(int i, int j); } public static class IFooExtensions { public static void Baz(this IFoo foo, int i, int j = 0) { foo.Bar(i, j); } } public class Foo { void Bar(int i, int j) { /* do stuff */ } }


No es necesario que el parámetro sea opcional en la implementación. Tu código tendrá más sentido entonces:

public interface IFoo { void Bar(int i, int j = 0); } public class Foo { void Bar(int i, int j) { // do stuff } }

De esta manera, no es ambiguo cuál es el valor predeterminado. De hecho, estoy bastante seguro de que el valor predeterminado en la implementación no tendrá ningún efecto, ya que la interfaz proporciona un valor predeterminado para él.


Lo que hay que tener en cuenta es lo que sucede cuando se utilizan frameworks de Mocking, que funcionan en función de la reflexión de la interfaz. Si se definen parámetros opcionales en la interfaz, el valor predeterminado se aprobará según lo declarado en la interfaz. Un problema es que no hay nada que te impida establecer diferentes valores opcionales en la definición.


Lo que es realmente extraño es que el valor que pone para el parámetro opcional en la interfaz realmente hace la diferencia. Supongo que debe preguntarse si el valor es un detalle de interfaz o un detalle de implementación. Hubiera dicho esto último, pero las cosas se comportan como la primera. El siguiente código muestra 1 0 2 5 3 7 por ejemplo.

// Output: // 1 0 // 2 5 // 3 7 namespace ScrapCSConsole { using System; interface IMyTest { void MyTestMethod(int notOptional, int optional = 5); } interface IMyOtherTest { void MyTestMethod(int notOptional, int optional = 7); } class MyTest : IMyTest, IMyOtherTest { public void MyTestMethod(int notOptional, int optional = 0) { Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); } } class Program { static void Main(string[] args) { MyTest myTest1 = new MyTest(); myTest1.MyTestMethod(1); IMyTest myTest2 = myTest1; myTest2.MyTestMethod(2); IMyOtherTest myTest3 = myTest1; myTest3.MyTestMethod(3); } } }

Lo que es interesante es que si su interfaz hace que un parámetro sea opcional, la clase que lo implementa no tiene que hacer lo mismo:

// Optput: // 2 5 namespace ScrapCSConsole { using System; interface IMyTest { void MyTestMethod(int notOptional, int optional = 5); } class MyTest : IMyTest { public void MyTestMethod(int notOptional, int optional) { Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); } } class Program { static void Main(string[] args) { MyTest myTest1 = new MyTest(); // The following line won''t compile as it does not pass a required // parameter. //myTest1.MyTestMethod(1); IMyTest myTest2 = myTest1; myTest2.MyTestMethod(2); } } }

Sin embargo, lo que parece ser un error es que si implementa la interfaz explícitamente, el valor que da en la clase para el valor opcional no tiene sentido. ¿Cómo en el siguiente ejemplo podrías usar el valor 9? Esto ni siquiera da una advertencia al compilar.

// Optput: // 2 5 namespace ScrapCSConsole { using System; interface IMyTest { void MyTestMethod(int notOptional, int optional = 5); } class MyTest : IMyTest { void IMyTest.MyTestMethod(int notOptional, int optional = 9) { Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); } } class Program { static void Main(string[] args) { MyTest myTest1 = new MyTest(); // The following line won''t compile as MyTest method is not available // without first casting to IMyTest //myTest1.MyTestMethod(1); IMyTest myTest2 = new MyTest(); myTest2.MyTestMethod(2); } } }