This behavior rattled me quite a bit:

C#:
  1. public class Derived : Base
  2. {
  3.    public override string Test(int test = 2)
  4.    {
  5.       return "Derived " + test.ToString();
  6.    }
  7. }
  8.  
  9. public class Base : IBase
  10. {
  11.    public virtual string Test(int test = 1)
  12.    {
  13.       return "base " + test.ToString();
  14.    }
  15. }
  16.  
  17. interface IBase
  18. {
  19.    string Test(int test = 3);
  20. }
  21.  
  22. class Program
  23. {
  24.    static void Main(string[] args)
  25.    {
  26.       Base b = new Base();
  27.       Console.WriteLine(b.Test());
  28.       IBase bi = b;
  29.       Console.WriteLine(bi.Test());
  30.       Derived d = new Derived();
  31.       Console.WriteLine(d.Test());
  32.       Base d2 = d;
  33.       Console.WriteLine(d2.Test());
  34.       IBase d2i = d2;
  35.       Console.WriteLine(d2i.Test());
  36.  
  37.       Console.Read();
  38.    }
  39. }

Would you have guessed that the output would be:

base 1
base 3
Derived 2
Derived 1
Derived 3

This is wrong on so many levels; I can't even start to tell you how appalled I am. Horrible! The debugging nightmares this will bring upon us... Because it is very counter intuitive!

Plus let's not forget call site integration and that whole bag of versioning problems...

Looking at all these potentially harmful side effects, I propose the following: Treat optional parameters like unsafe regions. Create a compiler flag that is off by default and must be set in order to allow the compiler to evaluate optional parameters - and by that make it a conscious choice for developers to go down that dangerous path. Plus to show people using a library with optional parameters: Buyer beware!

Seriously, think about it. Developer from all skill sets could benefit from said compiler flag.

- Newbies wouldn't know how to set the compiler flag - and would use regular (safe) overloads for their programming tasks. And by that they would be shielded from subtile bugs that might creep into their code that will utterly confuse them.

- I as a more advanced programmer would like to disable them when using an external API. Don't even bother allowing me to not set optional parameters. I am not that lazy, honestly. Maintainability is extremely important for me and I'd rather type in a couple of parameters than potentially getting into this debugging nightmare.

Post to Twitter Tweet this