Additional options for interfaces

Using C # 4.0 - creating an interface and a class that implements the interface. I want to declare an optional parameter in the interface and reflect it in the class. So, I have the following:

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

This compiles, but doesn’t look like that. The interface must have optional parameters, because otherwise it will not correctly reflect the signature of the interface.

Should I skip the optional parameter and just use a type with a null value? Or will it work as intended without any side effects or consequences?

+64
c # interface optional-parameters
Apr 02 2018-10-02T00:
source share
6 answers

You may consider an alternative to additional options:

 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); } } 

If you don't like the look of the new language feature, you don't need to use it.

+28
Apr 02 2018-10-14T00:
source share

What is really strange is that the value that you specify for an optional parameter in the interface really matters. I suppose you have a question if value is an interface detail or implementation. I would say the latter, but everything behaves like the first. For example, the following code outputs 1 0 2 5 3 7.

 // 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); } } } 

Interestingly, if your interface makes the parameter optional, then the class implementing it should not do the same:

 // 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); } } } 

However, it seems a mistake that if you implement the interface explicitly, the value that you give in the class for the optional value will be meaningless. How can you use the value 9 in the following example?

 // 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); } } } 

Eric Lippert wrote an interesting series on this subject: additional arguments

+57
Dec 19 '13 at 15:53
source share

You do not need to specify a parameter in the implementation. Then your code will make a little more sense:

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

Therefore, it is unambiguous that the default value. In fact, I am sure that the default value in the implementation will not have any effect, since the interface provides a default for it.

+4
Jul 31 '14 at 13:26
source share

How about this?

 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 */ } } 
+3
Apr 19 2018-12-12T00:
source share

What you need to consider is what happens when using Mocking frameworks that work based on interface reflection. If additional parameters are defined on the interface, the default value will be passed based on what is declared in the interface. One of the problems is that there is nothing to prevent you from setting various optional values ​​in the definition.

+2
Nov 14 '14 at 15:05
source share

Looks away, it will do what looks like what you want to accomplish.

+1
Apr 6 2018-10-06T00:
source share



All Articles