Arithmomaniac
Arithmomaniac

Reputation: 4804

Ambiguity with inheriting an optional-parameter base method

I have a base class with one optional default parameter, which a child class automatically provides a value for:

public class Merchant
{
    public string WriteResults(List<string> moreFields = null)
    {

        List<string> ListOfObjects = new List<string>() {Name, Address};
        if (moreFields != null)
        {
            ListOfObjects.AddRange(moreFields);
        }
            return ListOfObjects.ToString() //not real output
}


public class SpecificMerchant : Merchant 
{   
    new public string WriteResults()
        {
            return ((Merchant)this).WriteResults(new List<string>() {
                    Address, Phone //class-specific parameters
            });
        }
}

I used the new keyword when calling SpecificMerchant.WriteResults because both the parent and the base can take no parameters, but the compiler says this is unnecessary:

The member 'SpecificMerchant.WriteResults()' does not hide an inherited member. The new keyword is not required.

Why? Aren't I, in practice, overriding the parent method?

Upvotes: 4

Views: 1757

Answers (2)

Reed Copsey
Reed Copsey

Reputation: 564631

Because optional parameters are a compile time construct, not a runtime construct.

Your base class is always going to have a method with one parameter. The compiler just "substitutes" null at compile time if you call that method without an argument.

That being said, I would avoid trying to do what you're implementing above. Even if you remove the new keyword, which will let it compile, you're adding a lot of confusion. I would, personally, make the base class implementation virtual, if required, or add two methods to the base class and override one instead of using optional arguments.

For a good resource, I'd recommend reading James Michael Hare's post on Optional Parameters - He discusses the pitfalls, like this one, when you mix optional arguments with inheritance.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502086

No, you're not overriding it. You're providing a method with a different signature. Consider this:

new SpecificMerchant().WriteResults(new List<string>());

Could that possibly call the method in SpecificMerchant? No - you've specified an argument, and SpecificMerchant.WriteResults doesn't specify any parameters. That fact alone shows that it couldn't possibly override Merchant.WriteResults.

Your code could certainly cause confusion, as overloading in a type hierarchy often does even without optional parameters - but as far as the C# compiler and the CLR are concerned, these are very different methods... It so happens that both would be validate for a call with no arguments specified, but that's a different matter.

Upvotes: 2

Related Questions