Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional parameters for interfaces

Using c# 4.0 -- building an interface and a class that implements the interface. I want to declare an optional parameter in the interface and have it be reflected 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 it doesn't look right. The interface needs to have the optional parameters, because otherwise it doesn't reflect correctly in the interface method signature.

Should I skip the optional parameter and just use a nullable type? Or will this work as intended with no side effects or consequences?

like image 961
bryanjonker Avatar asked Apr 02 '10 14:04

bryanjonker


People also ask

Can we have optional parameter in interface?

When you call the method in the class you have to follow the class rules (the parameter is not optional in the class so you can't call the method without it), and in the second hand when you implement the interface you have to follow the interface rules,so you can override the methods with/without optional parameters.

What parameters are optional?

Optional parameters are defined at the end of the parameter list, after any required parameters. If the caller provides an argument for any one of a succession of optional parameters, it must provide arguments for all preceding optional parameters.

What is optional parameter in Java?

An optional parameter in Java, as the name implies, refers simply to a parameter that may be optional for a method invocation! It describes the possibility to call a method without specifying some of the arguments used in its definition! Parameters are variables that you can pass to a method or a function!

How do you write an optional parameter?

Here for the [Optional] attribute is used to specify the optional parameter. Also, it should be noted that optional parameters should always be specified at the end of the parameters. For ex − OptionalMethodWithDefaultValue(int value1 = 5, int value2) will throw exception.


2 Answers

What is really strange is that the value you put for the optional parameter in the interface actually makes a difference. I suppose you have to question whether the value is an interface detail or an implementation detail. I would have said the latter but things behave like the former. The following code outputs 1 0 2 5 3 7 for example.

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

What is kind of interesting is that if your interface makes a parameter optional the class implementing it does not have to 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);         }     } } 

What seems to be a mistake however is that if you implement the interface explicitly the value you give in the class for the optional value is pointless. How in the following example could you use the value 9?

// 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 exact topic: Optional argument corner cases

like image 64
Martin Brown Avatar answered Sep 28 '22 09:09

Martin Brown


You could consider the pre-optional-parameters alternative:

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 a new language feature, you don't have to use it.

like image 34
pdr Avatar answered Sep 28 '22 10:09

pdr