Udostępnij za pośrednictwem


Rozpoznawanie przeciążenia (Visual Basic)

Kompilator języka Visual Basic musi zdecydować, które przeciążenie ma być wywoływane, gdy procedura jest zdefiniowana w kilku przeciążonych wersjach. Podejmuje decyzję poprzez wykonanie następujących kroków:

  1. Dostępność. Eliminuje to wszelkie przeciążenia przy użyciu poziomu dostępu, który uniemożliwia kodowi jego wywołanie.
  2. Liczba parametrów. Eliminuje to wszelkie przeciążenia, które definiują inną liczbę parametrów niż zostają dostarczone podczas wywołania.
  3. Typy danych parametrów. Kompilator daje pierwszeństwo metodom instancji nad metodami rozszerzeń. Jeśli zostanie znaleziona jakakolwiek metoda wystąpienia, która wymaga tylko rozszerzenia konwersji w celu dopasowania do wywołania procedury, wszystkie metody rozszerzenia zostaną porzucone. Kompilator kontynuuje tylko z kandydatami metody wystąpienia. Jeśli taka metoda instancyjna nie zostanie znaleziona, przechodzi do metod instancyjnych i rozszerzeń. W tym kroku eliminuje wszelkie przeciążenia, dla których nie można przekonwertować typów danych argumentów wywołujących na typy parametrów zdefiniowane w przeciążeniu.
  4. Zawężanie konwersji. Eliminuje to wszelkie przeciążenia, które wymagają konwersji zawężającej z typów argumentów wywołujących do zdefiniowanych typów parametrów. Ten krok jest wykonywany niezależnie od tego, czy przełącznik sprawdzania typów (Deklaracja opcji Strict) jest ustawiony na On czy na Off.
  5. Najmniejsze rozszerzenie Kompilator uwzględnia pozostałe przeciążenia w parach. Dla każdej pary porównuje typy danych zdefiniowanych parametrów. Jeśli typy w jednym z przeciążeń rozszerzają się do odpowiednich typów w drugim, kompilator eliminuje ten ostatni. Oznacza to, że zachowuje przeciążenie, które wymaga najmniejszego rozszerzenia.
  6. Priorytet rozwiązywania przeciążenia. Kompilator usuwa wszelkie przeciążenia, które mają niższą OverloadResolutionPriorityAttribute niż najwyższa wartość spośród przeciążeń kandydatów. Każde przeciążenie bez tego atrybutu ma przypisaną wartość domyślną zero.
  7. Jeden kandydat. Kontynuuje rozważanie przeciążeń w parach, aż pozostanie tylko jedno przeciążenie i wtedy rozwiązuje wywołanie tego przeciążenia. Jeśli kompilator nie może zmniejszyć przeciążeń do jednego kandydata, generuje błąd.

Na poniższej ilustracji przedstawiono proces określający, którą z przeciążonych wersji w zestawie należy wywołać.

Diagram przepływu procesu rozwiązywania przeciążeń

Poniższy przykład ilustruje ten proces rozwiązywania przeciążenia.

Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short
Call z(r, s)
Dim p As Byte, q As Short
' The following statement causes an overload resolution error.
Call z(p, q)

W pierwszym wywołaniu kompilator eliminuje pierwsze przeciążenie, ponieważ typ pierwszego argumentu (Short) zawęża typ odpowiedniego parametru (Byte). Następnie eliminuje trzecie przeciążenie, ponieważ każdy typ argumentu w drugim przeciążeniu (Short i Single) rozszerza się do odpowiedniego typu w trzecim przeciążeniu (Integer i Single). Drugie przeciążenie wymaga mniejszego rozszerzenia, więc kompilator używa go do wywołania .

W drugim wywołaniu kompilator nie może wyeliminować żadnego z przeciążeń w oparciu o zawężenie. Eliminuje trzecie przeciążenie z tej samej przyczyny co w pierwszym wywołaniu, ponieważ może wywołać drugie przeciążenie z mniejszym rozszerzaniem typów argumentów. Jednak kompilator nie może rozwiązać problemu między pierwszym i drugim przeciążeniem. Każdy ma jeden zdefiniowany typ parametru, który rozszerza się na odpowiedni typ w drugim (Byte do Short, ale Single do Double). W związku z tym kompilator generuje błąd rozwiązywania przeciążenia.

Przeciążone argumenty Optional i ParamArray

Jeśli dwa przeciążenia procedury mają identyczne podpisy, z tą różnicą, że ostatni parametr jest zadeklarowany jako Opcjonalny w jednym i ParamArray w drugim, kompilator rozwiązuje wywołanie tej procedury w następujący sposób:

Jeśli wywołanie przekazuje ostatni argument jako Kompilator rozwiązuje wywołanie przeciążenia deklarującego ostatni argument jako
Brak wartości (argument pominięty) Optional
Pojedyncza wartość Optional
Co najmniej dwie wartości na liście rozdzielanej przecinkami ParamArray
Tablica dowolnej długości (w tym pusta tablica) ParamArray

Zobacz też