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
Anonymous
February 23, 2011
There's definitely some versioning issues to consider when using optional parameters with defaults. haacked.com/.../versioning-issues-with-optional-arguments.aspx haacked.com/.../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.Anonymous
February 23, 2011
The comment has been removedAnonymous
February 24, 2011
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);Anonymous
March 21, 2011
You raise some interesting points here; points i have myself considered and pondered. Are default parameters a blessing? Or a curse?