I have been using .NET 4 for a while now but I have to admit I never thought well of optional arguments. My impressions gravitated between
- method overloading for lazy people
- hiding hideously designed APIS (Office COM Automation, I am looking at you!)
And so I have not used the feature extensively. But during the last week I have found a couple of usages that I can label as “useful”. Let me tell you about them:
Replace property initializers with descriptive constructors
Property initializers are cool. A bit verbose, due to curly bracing, but cool. Have properties with sensible names and you have a very descriptive and flexible way of creating objects. Perhaps too flexible. No one enforces you a minimum set (unless places in a constructor) and it is easy to forget setting a property.
Problem is, that if you have a long parameter list it is really easy to loose overview and what is which. Furthermore, have more than two properties with the same type together and you are likely to make mistakes (is latitude the first one, or is it longitude?).
Can’t I have my cake and eat it too? Yes, but please, share.
Imagine a class that has loads of properties (all cohesive, before you ask ):
Use very expressive property initializers and forget something:
But, with a constructor that sets all properties...
...one can happily create an object, forget nothing and be expressive about what every argument means:
Specify just the argument that changes
Another case I recently found where they can dramatically improve readability is, not surprisingly, when one wants to override the default value
Let’s imagine we have a simple object that contains some collections:
While testing a piece of code that creates an instance of this
CollectionOfCollections in a way that only one of the collections is populated with a certain number of elements, while the other collections are to remain empty. One way of achieving it is asserting on each of the properties. I think that with very little work we can do much better:
What is inside this
A simple default nullable argument that gets translated either into a collection length constraint or to an empty collection constraint for each one of the collections.
Neat is not enough. One starts to reap the benefits really soon when several tests are written and each one asserts a different count on different collections.
LambdaPropertyConstraint<> is a typed counterpart to the out-of-the-box in NUnit’s
PropertyConstraint that allows passing further constraints to be applied to the member. It is part of Testing.Commons.NUnit.