Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# Optional Parameter Visibility

0.00/5 (No votes)
14 Oct 2014 1  
Optional parameter visibility in C#

Optional parameters in C# allow you to specify a default value of a method parameter. This lets you have several overloads of a method while still having a single method signature and implementation, which is easier to maintain. However, when you need to create an overload of a method, adding an optional parameter might not always be the right solution.

Consider the following simplified version of code that I found in the codebase I currently work on:

public class Client
{
    ...

    public void CloseAccount(Guid accountId, bool shouldCloseClient = true)
    {
        this.Accounts.Single(x => x.Id == accountId).Close();

        if(this.Accounts.All(x => x.State == AccountStates.Closed) && shouldCloseClient)
            this.Close();
    }

    ...
}

The scenario here is simple. Client can have multiple accounts and they might be closed at some points in time. Client class is the root of client aggregate, so closing the account must be done using the method demonstrated above. If we are closing the last account, the client should be closed too.

The method is called from outside by passing an accountId only. However, if this method is called from the inside of the class, a false is passed as shouldCloseClient parameter value. In this case, it is to stop recursion, because Client.CloseAccount calls Client.Close and vice versa. The actual code is more complex than what is demonstrated here, but I hope it can help illustrate the problem of abusing optional parameters.

The problem here is that shouldCloseClient parameter was meant to only be used from the inside of the Client class. That sounds like a case for applying private or protected access modifiers, but optional parameters cannot have them.

That’s why it is better to actually split the method into two, in the usual old school style:

public class Client
{
    ...

    public void CloseAccount(Guid accountId)
    {
        CloseAccountWithoutClosingClient(accountId);

        if(this.Accounts.All(x => x.State == AccountStates.Closed))
            this.Close();
    }

    private void CloseAccountWithoutClosingClient(Guid accountId)
    {
        this.Accounts.Single(x => x.Id == accountId).Close();
    }

    ...
}

By introducing a new method CloseAccountWithoutClosingClient, we are able to change its access modifier to private. As a bonus, we also get a chance to pick a more expressive name to distinguish it from the other method.

Every time you add an optional parameter to a method, consider how it will be used from outside and inside of the class and if you can benefit by actually splitting the method into two. It’s the same as with one-liners – less code is not necessarily better.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here