jordan
jordan

Reputation: 3546

Optional Parameters in Abstract method? Is it possible?

I have a abstract base class.

I have 2 derived classes from this base class.

Is there anyway that one of my classes can ignore the string parameter in the abstract overide usage? Or do I have to just send in a blank one and ignore it? (making readability drop slightly)

Can I have one function that has some sort of optional parameter so that both of the following derived classes would compile?

PS - The following code is riddled with in-compilable code for the example of what I would like to do

PS PS - Yes i have compiled the following code already - see above comment for outcome

public abstract class MyBaseClass
{                                            //optional string?
    public abstract void FunctionCall(int i, string s = "");
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }
}

Upvotes: 8

Views: 14194

Answers (3)

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

One possible way is to use extension methods to add missing overrides (which also works with interfaces)

static class MyBaseClassExtensions
{
       public void FunctionCall(this MyBaseClass item, int i)
       {
            item.FunctionCall(i, null);
       }
}

Upvotes: 3

David L
David L

Reputation: 33815

It will throw a compile error: "Abstract Inherited member 'MyBaseClass.FunctionCall(int, string)' is not implemented".

So no, the short answer is you can't do this.

Instead, you would have to do method overloading and implement BOTH abstract methods.

public abstract class MyBaseClass
{    
    public abstract void FunctionCall(int i);                                        
    public abstract void FunctionCall(int i, string s = "");
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s = "") { }

    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }

    public override void FunctionCall(int i) {}
}

However this seems quite messy. Perhaps the best option is to always use the optional parameter and simply not pass in a value if it is not needed or handle it as you already seem to be doing.

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s = "") 
    {
        if (!string.IsNullOrEmpty(s))
            MessageBox.Show(i.ToString());
        else
           // handle other path here
    }
}

Upvotes: 3

competent_tech
competent_tech

Reputation: 44931

If you don't absolutely need FunctionCall to be abstract, you can declare two versions of it:

public abstract class MyBaseClass
{
    public virtual void FunctionCall(int i)
    {
        this.FunctionCall(i, "");
    }
    public virtual void FunctionCall(int i, string s)
    {

    }
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }
}

Otherwise, if it must be abstract to ensure it is implemented, you could still add two versions, it just makes the inheritors more verbose:

public abstract class MyBaseClass
{
    public abstract void FunctionCall(int i);
    public abstract void FunctionCall(int i, string s);
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        throw new NotImplementedException();
    }
    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i)
    {
        throw new NotImplementedException();
    }
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }
}

Upvotes: 11

Related Questions