Peak at C# 4.0: optional parameter, named parameter and method resolution

Optional and named parameter is an awesome feature introduced in C# 4.0. Now C# combines some fancy features from dynamic languages like Python again (var knows why I say again. And the more dynamic dynamic is another topic, LOL).

Please note the “NEW:” comment for optional parameter declaration and named parameter assignment.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var top = new TestOptionalParameter();
double d = top.Demo(0); // #1

// int d = top.Demo(0, s: “test”); // NEW: named parameter.
}
}

class TestOptionalParameter
{
public int Demo(int i, string s = “demo purpose”) // #2 NEW: optional parameter declaration
{
Console.WriteLine(“int Demo(int i, string s = \”demo purpose\”)”);
return 0;
}

public double Demo(int i) // #3
{
Console.WriteLine(“double Demo(int i)”);
return 0;
}
}
}

But when combined with method name resolution, unconsidered condition may occur.

Try these changes and you will realize what you’ll pay for fancy new features: (Play it with VS2010. I don’t want to copy and paste several times and just modify one place of return type or variable value.)


Change #1
Change #2
Change #3
Why?




Works as expected. Matches 2nd Demo method.




change double to int


Easy to understand, the 1st Demo matches better. (Fully match in/out/return parameter, though there’s an optional parameter not specified when invoking the method)




add named parameter. change it to
double d = top.Demo(0, s: “test”);


still the 1st Demo matches better. Now named parameter takes place.






change int to double
Match 1st. No implicit conversion required for parameter.




change 0 to 0.0


Compile error. Explicit conversion required.




change 0 to 0.0
change int to double

Match 1st. No implicit conversion required for parameter.




Whenever add 2nd string parameter, named with “s” or unnamed.


Match 1st.












Some looks-hard-but-actually-straightforward-and-ideal conclusion:

  1. Whenever named or unnamed parameter used, method don’t accept these parameters will be out.
  1. If implicit conversion is NOT required, traditional method resolution goes first, then goes to match methods with optional parameter. (please note there’s some a-bit-evil details to be discussed.)
  1. If implicit conversion is required for parameter or return type, match method with matched implicit parameter first.
  1. When explicit conversion is required or specified error parameter name or value type, compile time error will be triggered.