Это зависит от TypeA
и TypeB
.
- Если применяется только один из них (например, нет преобразования из
null
в TypeB
, потому что это тип значения, а TypeA
является ссылочным типом), тогда будет выполнен вызов к соответствующему.
- В противном случае это зависит от отношений между
TypeA
и TypeB
.
- Если имеется неявное преобразование из
TypeA
в TypeB
, но неявное преобразование из TypeB
в TypeA
, то будет использоваться перегрузка с использованием TypeA
.
- Если имеется неявное преобразование из
TypeB
в TypeA
, но неявное преобразование из TypeA
в TypeB
, то будет использоваться перегрузка с использованием TypeB
.
- В противном случае вызов будет неоднозначным и не сможет скомпилироваться.
Подробные правила см. В разделе 7.4.3.4 спецификации C # 3.0.
Вот пример того, как это не было двусмысленным. Здесь TypeB
происходит от TypeA
, что означает неявное преобразование из TypeB
в TypeA
, но не наоборот. Таким образом, используется перегрузка с использованием TypeB
:
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)
}
}
Как правило, даже в случае неоднозначного вызова, чтобы убедиться, что используется определенная перегрузка, просто приведите:
Foo((TypeA) null);
или
Foo((TypeB) null);
Обратите внимание, что если это связано с наследованием в объявленных классах (т. Е. Один класс перегружает метод, объявленный его базовым классом), вы сталкиваетесь с совершенно другой проблемой, и вам нужно привести цель метода, а не аргумент .