Szukaj…


Uwagi

Proces rozwiązywania problemu przeciążenia opisano w specyfikacji C # , sekcja 7.5.3. Istotne są również sekcje 7.5.2 (wnioskowanie typu) i 7.6.5 (wyrażenia wywołania).

Sposób działania rozdzielczości przeciążenia prawdopodobnie zostanie zmieniony w C # 7. Uwagi projektowe wskazują, że Microsoft wprowadzi nowy system do określania, która metoda jest lepsza (w skomplikowanych scenariuszach).

Podstawowy przykład przeciążenia

Ten kod zawiera przeciążoną metodę o nazwie 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);
    }
}

Po wywołaniu metody Main zostanie wydrukowana

int
double

W czasie kompilacji, gdy kompilator znajdzie wywołanie metody Hello(0) , znajdzie wszystkie metody o nazwie Hello . W tym przypadku znajdzie dwa z nich. Następnie próbuje ustalić, która z metod jest lepsza . Algorytm określania, która metoda jest lepsza, jest złożony, ale zwykle sprowadza się do „wykonania jak najmniejszej liczby ukrytych konwersji, jak to możliwe”.

Zatem w przypadku Hello(0) nie jest wymagana konwersja dla metody Hello(int) ale niejawna konwersja liczbowa jest wymagana dla metody Hello(double) . Zatem pierwsza metoda jest wybierana przez kompilator.

W przypadku Hello(0.0) nie ma sposobu, aby przekonwertować 0.0 na int pośrednio, więc metoda Hello(int) nie jest nawet brana pod uwagę przy rozwiązywaniu problemów z przeciążeniem. Pozostaje tylko metoda, dlatego jest wybierana przez kompilator.

„parametry” nie są rozwijane, chyba że jest to konieczne.

Następujący program:

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

wydrukuje:

5
two
3

Wyrażenie wywołania Method(objectArray) można interpretować na dwa sposoby: pojedynczy argument Object który przypadkowo jest tablicą (więc program wyświetli 1 ponieważ będzie to liczba argumentów lub tablica argumentów podana w normalna forma, jakby metody Method nie mają słowa kluczowego params . W takich sytuacjach normalnych, forma nie rozszerzył zawsze ma pierwszeństwo. Więc wyjścia programu 5 .

W drugim wyrażeniu Method(objectArray, objectArray) stosuje się zarówno rozwiniętą formę pierwszej metody, jak i tradycyjną drugą metodę. W tym przypadku pierwszeństwo mają również nierozwinięte formularze, więc program wypisuje two .

W trzecim wyrażeniu Method(objectArray, objectArray, objectArray) jedyną opcją jest użycie rozszerzonej formy pierwszej metody, więc program wypisuje 3 .

Podanie wartości null jako jednego z argumentów

Jeśli masz

void F1(MyType1 x) {
    // do something
}

void F1(MyType2 x) {
    // do something else
}

i z jakiegoś powodu musisz wywołać pierwsze przeciążenie F1 ale z x = null , a następnie zrobić po prostu

F1(null);

nie zostanie skompilowany, ponieważ wywołanie jest niejednoznaczne. Aby temu przeciwdziałać, możesz to zrobić

F1(null as MyType1);


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow