C# – Warning From Explicitly Implementing an Interface with Optional Parameters

cc#-4.0compiler-warningsoptional-parameters

I was playing with optional parameters to see how they would work with interfaces and I came across a strange warning. The setup I had was the following code:

 public interface ITestInterface
 {
     void TestOptional(int a = 5, int b = 10, object c = null);
 }

 public class TestClass : ITestInterface
 {

     void ITestInterface.TestOptional(int a = 5, int b = 5, object c = null)
     {
        Console.Write("a=" + a + " b=" + b + " c=" + c);
     }
 }

The compiler gives me the following warnings:

  • The default value specified for parameter 'a' will have no effect because it applies to a member that is used in contexts that do not allow optional arguments
  • The default value specified for parameter 'b' will have no effect because it applies to a member that is used in contexts that do not allow optional arguments
  • The default value specified for parameter 'c' will have no effect because it applies to a member that is used in contexts that do not allow optional arguments

If I run this with the following code:

class Program
{
    static void Main(string[] args)
    {
        ITestInterface test = new TestClass();
        test.TestOptional();
        Console.ReadLine();
    }
}

I get the output of "a=5 b=10 c=" as I'd expect.

My question is what is warning for? What contexts is it referring to?

Best Answer

The problem with optional arguments in C# is whether the callee sees the object as a TestClass or an ITestInterface. In the first case, the values declared in the class apply. In the second case the values declared in the interface apply. It is because the compiler uses the statically available type information to construct the call. In case of an explicit interface implementation the method is never called 'for a class', always 'for an interface'

The C# Language Specification in 10.6.1 states:

If optional parameters occur in an implementing partial method declaration (§10.2.7) , an explicit interface member implementation (§13.4.1) or in a single-parameter indexer declaration (§10.9) the compiler should give a warning, since these members can never be invoked in a way that permits arguments to be omitted.