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);