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 😉

Previous post

This Afternoon in Boise

Next post

Book Review : Beyond Code


  1. November 10, 2008 at 2:35 am

    […] Be careful with optional parameters in C# 4.0 – Jan Van Ryswyck highlights some potentially surprising behaviour of derived types and optional parameters […]

  2. November 10, 2008 at 6:06 am

    […] Be Careful with Optional Parameters in C# 4.0 (Jan Van Ryswyck) […]

  3. November 10, 2008 at 12:00 pm

    Well done with this. I’ve not liked optional parameters since the day I first laid eyes on them and this makes me wary even more. Thanks for the heads-up.

  4. November 17, 2008 at 4:32 am

    Simple fix in the language design: ban overrides from changing the optional parameters?

  5. November 27, 2008 at 1:10 pm

    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…

  6. November 27, 2008 at 1:30 pm


    Similar example. 1 commenter tries it with VB and compiler will not allow you to change opt ional parameter values between overrides, another commenter tries it with c and gets the same behaviour as the c# 4.0 implementation.

    At least you know the lineage of the implementation (although it still sucks).