3
votes

Consider the following console application:

class Program
{
    static void Main()
    {
        MyInterface test = new MyClass();
        test.MyMethod();

        Console.ReadKey();
    }
}

interface MyInterface
{
    void MyMethod(string myString = "I am the default value on the interface");
}

class MyClass : MyInterface
{
    public void MyMethod(string myString = "I am the default value set on the implementing class")
    {
        Console.WriteLine(myString);
    }
}

The output from this program is:

I am the default value on the interface

(1) Why isn't there a way of specifying a parameter as optional on an interface without supplying a value. I consider the default value to be implementation detail. If we wrote this code in the pre-optional parameter style we would create two overloads in the interface and the default value would be specified in the implementing class. I.e. we would have:

interface MyInterface
{
    void MyMethod();

    void MyMethod(string myString);
}

class MyClass : MyInterface
{
    public void MyMethod()
    {
        MyMethod("I am the default value set on the implementing class");
    }

    public void MyMethod(string myString)
    {
        Console.WriteLine(myString);
    }
}

Which outputs as we would expect,

I am the default value set on the implementing class

(2) Why can't we override the default value in the implementing class!

2

2 Answers

4
votes

Default values in .Net are really compiler based syntactic sugar. At the call site the compiler adds in the default values for you. It cannot know the runtime type of your object at compile time so it must insert the value defined in the interface.

Hence, they cannot be 'overridden' in implementations because there is nothing to override.

Eric Lippert wrote a very interesting series of blog posts on the subject of optional arguments, the first of which can be found here.

Update
From your comments, what you're suggesting is either some form of 'virtual' parameter (in which the runtime type declares), which the CLR would have to 'know' about. I'm guessing that this implementation was ruled out because the costs (designing, documenting, implementing,testing etc) were too high compared to the benefits it gave (although this is only a guess!). Alternatively, there's the default delegating method option ie:

void M(bool y = false) { ... whatever ... }

Gets re-written by the compiler as:

void M() { M(false); }
void M(bool y) { ... whatever ... }

But going down this route leads to potentially unacceptable level of overloads once multiple optional arguments and named arguments are taken into considertaion.

3
votes

1) There's a flaw in your thinking. You say that the default value is an implementation detail. Interfaces are free of implementation details. By that logic, specifying a default value really doesn't belong in an Interface.

Just write the Interface using overloaded methods. Not only will the definition be more clear, but the interface will be more compatible when interfacing with other languages and you won't have the versioning issues that come with optional parameters.

2) Because the interface defines an operational contract. The interface says the default must be something...therefore the class must implement it that way.