Default parameters in C#

From an internal discussion we’re having on the advisability of using default parameters in C#:

Currently, the pain and limitation of doing overloads forces you to rethink how a method should work. Consider the following:

 Process(int a);

Process(int a, float b);

Process(int a, float b, string c);


If I now need to change how that works in some situations, I could add a boolean to control that behavior, but it’s not obvious how to add it to the current overload scheme. I can do something like:


Process(int a);

Process(int a, bool doBackground);

Process(int a, float b);

Process(int a, float b, bool doBackground);

Process(int a, float b, string c);

Process(int a, float b, string c, bool doBackground);


But not only is that a bit hard to write, it’s a bit confusing, and if I need to add another parameter in the future, I’m pretty much SOL. So, that forces me to consider the alternatives; should I go with a “Settings” class (like XmlWriterSettings), should I live with it, or should I think about refactoring the process to simplify things? That forced stop gives me the chance to think about better ways to approach things.


With default parameters, it’s going to be really tempting to just add a default, and it’s more likely you’ll end up with methods like this:


Process(int a, float b, string c, bool doBackground = false, bool writeToLog = true, string database=null, string method=”jumble”);


That is bad not only for the caller of the api, but it suggests that the process method is pretty complex internally.


On the other hand, I can’t count how many times I’ve written a well-constrained series of overloads that purely added in default values and had to write nearly duplicate xml docs for each of them, and I’d be really happy to save that time and not have those methods clutter up the code. 


Or, to put it another way, default parameters are great if you use them to simplify scenarios that you would have written with overloads. If you start doing things that would be hard to express in overloads, I’d look harder at the overall design.


Comments (4)

  1. haacked says:

    There's definitely some versioning issues to consider when using optional parameters with defaults.…/versioning-issues-with-optional-arguments.aspx…/more-optional-versioning-fun.aspx

    This led us to remove much of our usage of them in ASP.NET except for maybe a few places where we didn't think we'd ever change them.

  2. Shuggy says:

    The thing I don't like is that they are most useful as a replacement for a bunch of overloads _but_ the semantics of the defaults is different. Instead of being baked into the dll that defines them they are backed into the dlls that compile against them.

    If you make heavy use of overloads to maintain binary compatibility then it's a real pain.

    I really wish there was a simple way to just create overloads that deferred to the others (and could have xdoc links to the master one (along with an indication of what the defaults were)

    some thing like:

    ///<docref cref="Frob(int,string)"><paramref name="s"> is string.Empty</docref>

    public Foo Frob(int x)


       return Frob(x, string.Empty);


    ///<summary>blah blah blah</summary>

    public Foo Frob(int x, string s)



    note how the paramref is refering to a parameter on the master, not the current method

    for overloads using compile time literals you could do very terse stuff like:

    public overload Foo Frob(int x) ~> Frob(x, "");

    And have the document system auto fill everything for you. Though often being limited to compile time literals would be a pain I image it would in fact cover 70% of my needs (so long as default(T) was allowed on generic methods).

    And hey, I found a use for the nadj (…/a-face-made-for-email-part-four.aspx) 🙂

  3. Marc Brooks says:

    I swore to my teddy bear to NEVER add an override that takes a boolean. I've found over the years that the meaning of true or false is so easily lost, and so easily forgotten which is the "without argument" state that I've gone to using an Enum that clearly described the behavior.

    Years later:

    var tweets = TweetRepo.GetLatestTweets(tweepId, DirtyWords.ReplaceNaughty);

    Is much clearer than:

    var tweets = TweetRepo.GetLatestTweets(tweepId, true);

  4. Ryan CrawCour says:

    You raise some interesting points here; points i have myself considered and pondered. Are default parameters a blessing? Or a curse?