65.9K
CodeProject is changing. Read more.
Home

Optional Parameters that Aren't (optional, that is)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (10 votes)

Sep 13, 2016

CPOL

1 min read

viewsIcon

14381

This came as a mild surprise

Heads Up

I have an existing class that has a method called UpdateStatus that updates a list of stringsdisplayed in the UI. I created another class that I wanted to get status messages from, but I didn't want to change the original class to expose it's UpdateStatus method.

My solution was to pass the method as an Action to the constructor of the new class.

The method prototype (in the original class) looks like this - notice the default parameter:

public class MyOldClass
{
    public void UpdateStatus(string msg, bool isError=false)
    {...}
    
    // this method instantiates MyNewClass
    private void SomeOtherMethod()
    {
        MyNewClass myClass = new MyNewClass(this.UpdateStatus);
    }
}

The class I was writing looked like this:

public class MyNewClass
{
    public Action<string, bool> UpdateStatus { get; private set; }
    
    public MyClass(Action<string, bool> updateStatus)
    {
        this.UpdateStatus = updateStatus;
    }
}

When I tried to call the action delegate within the new class, like so:

this.UpdateStatus("some text");

I found out that any optional parameters that might be specified in the actual method's prototype revert to *required* parameters, thus forcing me to specify a value for the isError parameter:

this.UpdateStatus("some text", false);

In case you're interested, you cannot define the Action property (in the new class) as having a default parameter, either.

This is just a little heads up for anyone else doing the same thing.

Additional Info

I could have used a delegate:

public delegate void UpdateStatusDelegate(string msg, bool isError=false);
public UpdateStatusDelegate UpdateStatus { get; set; }

public MyNewClass(UpdateStatusDelegate updateStatus)
{
    this.UpdateStatus = updateStatus;
}

...allowing me to keep the default parameter paradigm, but that's more a matter of style than propriety in this case. If I had wanted to use ref or out parameters, a delegate would have been required since an Action also doesn't support those types of parameters.

History

  • 14 SEP 2016 - Made the text a little clearer as to what I was doing and what was happening.
     
  • 13 SEP 2016 - Original publication.