March 14, 2010

C# 4.0: Code might smell with Optional Parameters

      I wrote few tests to understand Named, and Optional Parameters, and also reflected them in reflector to see what happens behind the scene.Now let's think about their impact on code readability.

      These would be very useful in calling Office Automation API. We don't need to worry about passing Type.Missing to zillion arguments, we can now just pass necessary arguments with the use of Named parameters.

       I can see misuse as well. I won't be surprised to see functions with lengthy optional parameters. That brings me a question: How many parameters can a function  have? I often find myself  debating whether a parameter can be an instance field of current object, or some other object. Let's turn to an expert, and see what he thinks.

        Uncle Bob talked about functional arguments in his articles for InformIT, and there is a dedicated chapter in his book Clean Code.  He says in this article Avoid Too Many Arguments, "Functions should have a small number of arguments. No argument is best, followed by one, two, and three. More than three is very questionable and should be avoided with prejudice.".

Clean Code: A Handbook of Agile Software Craftsmanship         He also recommends to not to have boolean arguments, as this is an indication that a function is doing two things. He writes in this article Eliminate Boolean arguments  "Boolean arguments loudly declare that the function does more than one thing. They are confusing and should be eliminated.". "Arguments are hard. They take a lot of conceptual power.", Uncle Bob writes in the book Clean Code.Writing unit tests for function with many arguments will be harder. Tests should cover all possible combinations of the parameters.
Refactoring: Improving the Design of Existing Code
   
       If you end up having function with more arguments, you can try following refactorings. Related Refactorings: (The book refered in this catalog) 
Replace Parameter with Method
Replace Parameter with Explicit Methods
Replace Record with Data Class
Parameterize Method
Remove Parameter