C# Language
Rozdzielczość przeciążenia
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);