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