C#: Passing null to overloaded method – which method is called?

It depends on TypeA and TypeB.

  • If exactly one of them is applicable (e.g. there is no conversion from null to TypeB because it’s a value type but TypeA is a reference type) then the call will be made to the applicable one.
  • Otherwise it depends on the relationship between TypeA and TypeB.
    • If there is an implicit conversion from TypeA to TypeB but no implicit conversion from TypeB to TypeA then the overload using TypeA will be used.
    • If there is an implicit conversion from TypeB to TypeA but no implicit conversion from TypeA to TypeB then the overload using TypeB will be used.
    • Otherwise, the call is ambiguous and will fail to compile.

See section 7.4.3.4 of the C# 3.0 spec for the detailed rules.

Here’s an example of it not being ambiguous. Here TypeB derives from TypeA, which means there’s an implicit conversion from TypeB to TypeA, but not vice versa. Thus the overload using TypeB is used:

using System;

class TypeA {}
class TypeB : TypeA {}

class Program
{
    static void Foo(TypeA x)
    {
        Console.WriteLine("Foo(TypeA)");
    }

    static void Foo(TypeB x)
    {
        Console.WriteLine("Foo(TypeB)");
    }

    static void Main()
    {
        Foo(null); // Prints Foo(TypeB)
    }
}

In general, even in the face of an otherwise-ambiguous call, to ensure that a particular overload is used, just cast:

Foo((TypeA) null);

or

Foo((TypeB) null);

Note that if this involves inheritance in the declaring classes (i.e. one class is overloading a method declared by its base class) you’re into a whole other problem, and you need to cast the target of the method rather than the argument.

Leave a Comment