C# Language
Разрешение перегрузки
Поиск…
замечания
Процесс разрешения перегрузки описан в спецификации C # , раздел 7.5.3. Также актуальны разделы 7.5.2 (вывод типа) и 7.6.5 (выражения вызова).
Как работает разрешение перегрузки, вероятно, будет изменено на C # 7. Замечания по дизайну показывают, что Microsoft развернет новую систему для определения того, какой метод лучше (в сложных сценариях).
Пример базовой перегрузки
Этот код содержит перегруженный метод с именем Hello :
class Example
{
public static void Hello(int arg)
{
Console.WriteLine("int");
}
public static void Hello(double arg)
{
Console.WriteLine("double");
}
public static void Main(string[] args)
{
Hello(0);
Hello(0.0);
}
}
Когда вызывается метод Main , он будет печатать
int
double
Во время компиляции, когда компилятор находит вызов метода Hello(0)
, он находит все методы с именем Hello
. В этом случае он находит два из них. Затем он пытается определить, какой из методов лучше . Алгоритм определения того, какой метод лучше, сложный, но он обычно сводится к «сделать как можно меньше имплицитных преобразований».
Таким образом, в случае Hello(0)
преобразование не требуется для метода Hello(int)
но для метода Hello(double)
требуется неявное числовое преобразование. Таким образом, первый метод выбирается компилятором.
В случае Hello(0.0)
нет возможности конвертировать 0.0
в int
неявно, поэтому метод Hello(int)
даже не рассматривается для разрешения перегрузки. Остается только метод, поэтому он выбирается компилятором.
«params» не расширяется, если это необходимо.
Следующая программа:
class Program
{
static void Method(params Object[] objects)
{
System.Console.WriteLine(objects.Length);
}
static void Method(Object a, Object b)
{
System.Console.WriteLine("two");
}
static void Main(string[] args)
{
object[] objectArray = new object[5];
Method(objectArray);
Method(objectArray, objectArray);
Method(objectArray, objectArray, objectArray);
}
}
будет печатать:
5
two
3
Вызов Method(objectArray)
можно интерпретировать двумя способами: одним аргументом Object
который является массивом (поэтому программа будет выводить 1
потому что это будет число аргументов или массив аргументов, приведенный в нормальная форма, как бы метод Method
не имеет ключевое слово params
. В таких ситуациях нормальная, нераскрытая форма всегда имеет приоритет. Таким образом, программа выводит 5
.
Во втором выражении Method(objectArray, objectArray)
, как расширенная форма первого метода, так и традиционный второй метод. В этом случае также нерасширенные формы имеют приоритет, поэтому программа печатает two
.
В третьем выражении Method(objectArray, objectArray, objectArray)
единственным вариантом является использование расширенной формы первого метода, и поэтому программа печатает 3
.
Передача null в качестве одного из аргументов
Если у вас есть
void F1(MyType1 x) {
// do something
}
void F1(MyType2 x) {
// do something else
}
и по какой-то причине вам нужно вызвать первую перегрузку F1
но с x = null
, а затем просто
F1(null);
не будет компилироваться, поскольку вызов неоднозначен. Чтобы противостоять этому, вы можете сделать
F1(null as MyType1);