Running with Code Like with scissors, only more dangerous

15Jan/080

My C# 4.0 Wishlist, Part 2 : Default/Optional Parameters

When I was first getting into C# (about .NET 1.0 Beta 2), I saw that it didn’t support optional parameters.  The explanation was simple enough: method overloads supported an alternative method of default or optional parameters.  I thought that it was probably a useful choice.  But, check this out:

   1:  public static class MessageBox
   2:  {
   3:      static void Show(string message)
   4:      {
   5:          Show(message, null, MessageBoxButtons.OK, MessageBoxIcon.Information);
   6:      }
   7:   
   8:      static void Show(string message, string title)
   9:      {
  10:          Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
  11:      }
  12:   
  13:      static void Show(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
  14:      {
  15:          // actually perform the showing
  16:      }
  17:   
  18:      // and more overloads
  19:  }

This is pretty lame, isn’t it?  Why can’t I just do everything with a single method?

   1:  public static class MessageBox
   2:  {
   3:      static void Show(string message, string title = "", MessageBoxButtons button = MessageBoxButtons.OK, 
   4:          MessageBoxIcon icon = MessageBoxIcon.Information);
   5:  }

So, the question is, how precisely could this work?  Well, let’s take a look at how this works in Visual Basic.

   1:  Public Class MessageBox
   2:      Public Shared Sub Show(ByVal message As String, Optional ByVal title As String = "", _
   3:                             Optional ByVal buttons As MessageBoxButtons = MessageBoxButtons.OK, _
   4:                             Optional ByVal icon As MessageBoxIcon = MessageBoxIcon.Information)
   5:      End Sub
   6:  End Class

Visual Basic turns this into a method and annotates the parameter list with attributes.  In C# we could express it like this:

   1:  public static class MessageBox
   2:  {
   3:      static void Show(string message, 
   4:          [Optional]
   5:          [DefaultParameterValue("")]
   6:          string title, 
   7:          [Optional]
   8:          [DefaultParameterValue(MessageBoxButtons.OK)]
   9:          MessageBoxButtons buttons, 
  10:          [Optional]
  11:          [DefaultParameterValue(MessageBoxIcon.Information)]
  12:          MessageBoxIcon icon)
  13:      {
  14:   
  15:      }
  16:  }

In languages that support optional parameters, the compiler provides parameters, so that a call that leaves off optional parameters looks (in IL) like a call that included the parameters.

I suggest that we use a compiler trick – dump the attributes and actually implement the overloads.  This has the awesome benefit of being entirely compiler-dependent and entirely backwards-compatible even to .NET 2.0.  We can even include one overload with the attributes included, so that development tools and compilers that use the attributes can tell the user about the optional parameter information, and the existing compilers can compile against a library using the new methods.

Consider this overload based on the above demonstrated Show method.

   1:  public static class MessageBox
   2:  {
   3:      static void Show(string message, MessageBoxIcon icon)
   4:      {
   5:          Show(message, "", MessageBoxButtons.OK, icon);
   6:      }
   7:  }

This function has the advantage of being inline-able, even if it means a slightly (and I mean ever-so-slightly) hit to file size.  I’m not saying it’d be good or effective to have 10 optional parameters – just that it wouldn’t be bad to have a few.

Finally, my suggestion for the syntax of how this all should work out – use the default keyword for each item when you want to specify options:

   1:  void Go()
   2:  {
   3:      MessageBox.Show("This is a test.", default, MessageBoxButtons.OK);
   4:  }

CLI implementation provides an attribute on the actual implementing method so that we can figure out which is the actual default value – the compiler then has the option of whether to call substituting in the actual value (as it’s implemented in VB now) or call the correct overload (which is what the current C# compiler would do).

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

ERROR: si-captcha.php plugin says GD image support not detected in PHP!

Contact your web host and ask them why GD image support is not enabled for PHP.

ERROR: si-captcha.php plugin says imagepng function not detected in PHP!

Contact your web host and ask them why imagepng function is not enabled for PHP.

No trackbacks yet.