It depends on TypeA and TypeB.
- If exactly one of them is applicable (e.g. there is no conversion from
nulltoTypeBbecause it’s a value type butTypeAis a reference type) then the call will be made to the applicable one. - Otherwise it depends on the relationship between
TypeAandTypeB.- If there is an implicit conversion from
TypeAtoTypeBbut no implicit conversion fromTypeBtoTypeAthen the overload usingTypeAwill be used. - If there is an implicit conversion from
TypeBtoTypeAbut no implicit conversion fromTypeAtoTypeBthen the overload usingTypeBwill be used. - Otherwise, the call is ambiguous and will fail to compile.
- If there is an implicit conversion from
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.