Поиск…


замечания

Процесс разрешения перегрузки описан в спецификации 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);


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow