tags:

views:

128

answers:

1

I have the following code:

    [TestMethod]
    public void TestFoo()
    {
        Foo(null);
    }

    private void Foo (object bar)
    {
        Console.WriteLine("Foo - object");
    }

    private void Foo (string bar)
    {
        Console.WriteLine("Foo - string");
    }

and when I run the test "TestFoo()", the console output is "Foo - string". How does the compiler decide which method to call?

+14  A: 

It applies the "better conversion" rules (7.4.3.3 of the C# 3 spec) as part of overload resolution (section 7.4.3 in general).

Basically in this case there's a conversion from string to object, but not from object to string. Following the rules, that means the conversion from null to string is better than the one from null to object, so the overload with the string parameter is used.

Overload resolution can get extremely complicated when the following factors get involved:

  • There could be generic methods in the candidate set
  • If there are generic methods, type inference is applied to each of them separately, giving different conversion opportunities
  • If any arguments are method groups, they could be converted to different delegate types - possibly even using different method signatures if the named method group also has multiple overloads
  • Inheritance can lead to surprising results
  • Parameter arrays (params) add to the fun
  • Optional parameters in C# 4 contribute to the decision too

Basically overloading can be a real can of worms - where possible, design overloads so that only one of them will ever be a valid target of any given method call, so that you don't need to worry about the detailed rules.

Jon Skeet