2

I'm supporting some code that has optional parameters and interfaces.

As a simplified example: I have a default of 2 in the interface, and 1 in the implementation class.

public interface IOptionalInterface
{
    int Get(int x = 2);
}

public class ClassX : IOptionalInterface
{
    public int Get(int x = 1)
    {
        return x;
    }
}

This code passes, as I expected.

        Assert.AreEqual(new ClassX().Get(), 1);

However, when I pass the class back as the interface, and invoke it later, I get the optional parameter from the interface; which surprised me.

    private IOptionalInterface Build()
    {
        return new ClassX();
    } 

    public void Expect1()
    {
        var y = Build();
        Assert.AreEqual(y.Get(), 1);  // fails, it returns 2.
    }

What are the major design considerations that I'm missing that make this preferential?

Is there a clean way to assure the implementing class gets to set the default value?

JB.
  • 83
  • 1
  • 6

2 Answers2

3

Optional parameters are a purely compile-time feature invoked at the callsite.

When you call a method with an optional parameter, the compiler looks up the default value of that parameter and inserts that literal value in the invocation.
Therefore, the default value is resolved based on the compile-time type of the callsite.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

It's because - like extension methods - optional parameters are a compiler trick not a true language feature.

So appropriately - solve the issue with an extension method:

public interface IDoSomething {
    void DoThis(int parameter);
}

public static class DoSomethingDefaults {
    public static void DoThis(this IDoSomething x) {
        x.DoSomething(123); //default value
    }
}

///
new ClassThatImplementsDoSomething().DoThis();
new ClassThatImplementsDoSomething().DoThis(456);

It's not as super-slick looking as true optional parameters but for most purposes they do the same thing and work correctly.

Keep the defaults alongside with your interface (I recommend the same file even) and hopefully it won't be too hard for a newcomer to your project to trace through what is going on.

George Mauer
  • 117,483
  • 131
  • 382
  • 612