Method Overloading in C#

November 2, 2010 5:06 am

In the words of a 90's action movie: "Alright, pop quiz".

What would the output of the following program be:

C#:
  1. class Program
  2. {
  3.     public static void Main(string[] args)
  4.     {
  5.         int x = 0;
  6.         int y = 1;
  7.         Test(x);
  8.         Test(y);
  9.         Test(1);
  10.         Test(0);
  11.     }
  12.     public static void Test(object obj)
  13.     {
  14.         Console.WriteLine("Object Overload");
  15.     }
  16.     public static void Test(System.DayOfWeek day)
  17.     {
  18.         Console.WriteLine("Enum Overload");
  19.     }
  20. }

If you run this code under .NET 3.5 you will see the following:

Object Overload
Object Overload
Object Overload
Enum Overload

So we pass in the same type (Int32) but we end up calling different method overloads. It also seems that the specific values that we are using matters. That seems a bit counter intuitive.

What is going on? What is happening is that the C# compiler is resolving the Test(0) call to the enum overload method. The reason can be found in the C# Language Specification 4.0:

the literal 0 implicitly converts to any enum type

So the literal 0 will resolve to the enum overload method due to the implicit conversion. That is why the call with a variable set to 0 resolves to the expected object overload.

This can cause some confusion when using a class that has an enum and object overload. A common scenario is when using SqlParameter. If you specify a literal 0 to the SqlParameter constructor then it will use the overload SqlParameter(String, SqlDbType) which will set the type of the parameter and not the value and is probably not what is wanted. To get around this simply cast or convert to any object type. Since we are using an int then converting to Int32 will make our intent clear:

C#:
  1. Parameter p = new SqlParameter("@pname",
  2.     Convert.ToInt32(0));

An alternative would be to use a variable instead of a literal:

C#:
  1. private static readonly int zero = 0;
  2. ...
  3. Parameter p = new SqlParameter("@pname", zero);

No Responses to “Method Overloading in C#”

Care to comment?