Optional Parameters Are Gaining Ground in .NET

by Jonathan Allen on Jul 06, 2010 |

Optional parameters have always been part of .NET, but with C# unwilling to support it, using them was generally considered taboo unless work with COM libraries. Now that C# 4 does support them, we are starting to see them used for a lot more than just legacy code. Other uses include interoperability with dynamic languages, immutable data structures, and various parts of ASP.NET MVC.

COM is of course still the primary use for optional parameters in .NET. When dealing with libraries such as Office which can have 20+ parameters on function, manually specifying every argument is incredibly tedious. And without labels, one is left to the error prone process of counting slots to determine which argument is mapped to which parameter. For those unfamiliar with COM, it was created back in the days when not all of the popular languages supported function overloading. Since functions containing optional parameters could always be treated as normal functions, this made a lot of sense at the time.

In addition to the complaints of COM programmers, the C# team was using C# 4 as a chance to introduce late binding so they could support the DLR. In fact, that was the only feature they actually wanted to support, everything else just came along for the ride. Optional parameters are needed in dynamic languages, as the lack of explicit typing means they can’t overload functions based on parameter types.

With the increased availability of multi-core and multi-CPU machines, discussions about parallelism and concurrency are becoming more common. A common topic is the usefulness of immutable data structures and the problems with defining them. If every property needs to be set then a standard constructor makes sense. But if most properties are optional, things become somewhat tricky. Overloaded constructors only work to a certain point, after which people using Java or older versions of C# they would often turn to builder patterns. But with optional parameters one can easily do the job with a single constructor.

Controllers in ASP.NET MVC 2 now support default values for query string parameters. While they can be specified using attributes, the most succinct way to indicate them is to use the optional parameter syntax in C# or VB.

Microsoft’s Razor view engine for ASP.NET MVC uses optional parameters for HTML helpers. This allows them to add a lot of options to the helper while providing a self-documenting coding style. Razor does take things one step further, as it also supports automatically turning expressions into delegates without the lambda or anonymous delegate syntax.

There are some places where we expect optional parameters to never be found. The Common Language Specification, which defines the subset of the CLR that all languages should support, explicitly disallows a reliance on optional parameters. This means they are not a candidate for use in the Base Class Library and will probably never been seen in any of the other libraries shipped as part of the .NET Framework. But for the out-of-band libraries released via CodePlex the rules are considerably laxer.

Rate this Article


Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Nice, but only when it makes sense by Francois Ward

These are nice in many cases, but there was a reason why C# and some other languages didn't implement them originally, and between fluents APIs, optional parameters, object initializers, and other such features, these reasons are quickly biting us in the rear.

API discoverability is nil, you end up with APIs that you cannot use without extensive documentation, intellisense doesn't help you, you don't know what parameters need to be set or not...

It still makes sense when the parameters REALLY are optional and their usage are obvious, for legacy purpose, for DLR interop, etc. But more and more I see APIs being designed around these things for convenience and little more (usually convenience of the developer, or "because its so much cooler!"). These are extremely problematic.

The example that comes to mind is the Castle fluent registration API (I'm going on a Tangent here, but the same applies to optional parameters).

Amazing tool when used well, but history has shown, even recent history, that API designers do not use these tools well. At all.

Mess of spaghetti code caused by poorly designed APIs in 5...4...3....

Razor and ASP.NET MVC Helpers are complete garbage by john zabroski

Anybody who understands anything at all about programming language semantics is not going to be impressed by the fact Razor lets you type less. It doesn't fix the fact that ASP.NET Server Page model is stupid, and that ASP.NET MVC Helpers have arbitrarily stupid overloads and that it is very easy to end up invoking the wrong function.

The funny thing is that some of these Helpers, especially in the Beta bits, use anonymous types and reflection in a perverse way just so developers can get syntactic sugar for a Map data type. Please, just pick Ruby if all you care about is syntactic sugar.

I've had enough of bad design ideas from ScottGu and ASP.NET team.

Re: Razor and ASP.NET MVC Helpers are complete garbage by john zabroski


Let me just add that in general I dislike optional parameters. This comment is directed solely towards you, because you should know this. If you don't, pay attention right now.

Most good coding guidelines outright bad the use of default parameters. For one, they are not versionable. If you add them, the only reason for doing so is to consolidate methods and avoid method proliferation. For example, if a method in ASP.NET does not properly separate mechanism from policy, then the ASP.NET team could change the method so that the default code path through the system is the same as in the previous version. They can do this by using a default parameter whose value maps to logic from the previous version of the system. Some people prefer this to adding new methods to a class that overload on the method name.

In general, the reason why you should avoid default parameters in all other cases is that your methods should not have concrete dependencies. Instead, the dependencies should be supplied to the method. With any decent IoC container and dependency injection, default parameters are handled for you on a per-application basis. This strategy assumes that when you wrote your code you understood the problem domain and appropriately separated policy from mechanism, WHAT NOT HOW. This also means default values are defined based on their caller, rather than by some client API author.

Contributing editors,

It is not enough to just post articles with little commentary. You need to be good programmers and know what is considered good programming style in industry.

Re: Nice, but only when it makes sense by john zabroski

I agree completely. Whoever wrote the code for ASP.NET MVC Html Helpers does not know how to design API well. Take my deconstructive critique for an example of how dumb that code is:

Who cares if "the use of optional parameters is gaining ground".

News at 12: People jumping off bridge. If you wish to follow, the location is...

Re: Razor and ASP.NET MVC Helpers are complete garbage by Jonathan Allen

I believe that the versioning problems with optional parameters are grossly exaggerated. Changing a default value is always a problem, it doesn’t matter if that default is exposed via an optional parameter or hidden inside an overridden method. This is why I have a rule that defaults can only be 0/null/false.
Of course this only applies to public APIs that are shipped. If you are working on an internal application, such as a web site, the default versioning issue isn’t a concern at all because it should just be picked up on the next build.

Re: Razor and ASP.NET MVC Helpers are complete garbage by john zabroski

Where are you going with this?

There are standard OO refactorings for handling situations where a configuration value was hidden previously and now needs to be made publically tweakable, e.g. converting a hardcoded value into an enumerated data type.

This is why I have a rule that defaults can only be 0/null/false.

I am sorry, but I have no idea why this 0/null/false rule helps anything. I don't even want to know why you think it does. I'm just going to tell you the RIGHT way to program: If you have a situation where you want to pass in "0/null/false", especially null, then replace it with an Option type and use pattern matching to do appropriate multiple dispatch. This is one area where C# 4 is poor, since it does not support pattern matching.

Inversion of control containers provide a separation of "default value" at three critical points: (1) the library source code (2) the application domain (3) the application source code

This decoupling tends to work well in practice.

I believe that the versioning problems with optional parameters are grossly exaggerated.

I believe that you should avoid problems instead of creating them with the use of bad techniques.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

6 Discuss
General Feedback
Marketing and all content copyright © 2006-2016 C4Media Inc. hosted at Contegix, the best ISP we've ever worked with.
Privacy policy

We notice you're using an ad blocker

We understand why you use ad blockers. However to keep InfoQ free we need your support. InfoQ will not provide your data to third parties without individual opt-in consent. We only work with advertisers relevant to our readers. Please consider whitelisting us.