Be careful with optional parameters in C# 4.0

I’ve been playing with the Visual Studio 2010 CTP bits, and I tried to see what named and optional parameters in C# 4.0 can bring to the table. Although they are minor language enhancements at best, they can cause a lot of grief as well.

In my former life as a C++ developer, optional parameters were quite handy in some cases to remove some ceremonial code for providing obvious overloads of a method. Since I came over to the .NET platform, I actually don’t miss optional parameters. I just wanted to share a common abuse of optional parameters that you should be aware of. The following code illustrates this:

public class Base { public virtual void Foo(Int32 x = 1) {} } public class Derived { public override void Foo(Int32 x = 2) {} } ... Base f0 = new Base(); f0.Foo(); // Invokes Foo(1) Base f1 = new Derived(); f1.Foo(); // Also invokes Foo(1) Derived f2 = new Derived(); f2.Foo(); // Invokes Foo(2)

This is something you have to watch out for. The object’s member function silently takes different arguments depending on the static type you use. This violates the principle of least surprise and is a general PITA. Don’t violate the method contract that has been provided by the base class.

Don’t say I didn’t warn you 😉

Published by

Jan Van Ryswyck

Hi, thank you for visiting my blog and reading all the crap that I'm posting here. I'm a senior software engineer at SD WORX. Developing software is one of my greatest passions in life, and I enjoy doing it every single day. I've got three kids (Len, Lisa & Laura) who constantly remind me that there is more in life than just programming all day. They are the greatest kids in the whole world. And last but not least, there's my girlfriend who is my inspiration in life. You can always contact me at jan_dot_van_dot_ryswyck at gmail.com

6 thoughts on “Be careful with optional parameters in C# 4.0”

  1. Why? why? why would they choose to make it operate in this manner. It should be the instantiated type that determines the method that is called.

    @Daniel: There is no need for that approach, when you define something as virtual and then override it in a descendent class, you effectively replace the method in the parent class. If this behaviour was continued for methods with optional parameters then f1.Foo(); should invoke Foo(2).

    Off to see if I can find any reasoning behind this…

Comments are closed.