Wszystko jest wcześnie wiązane w C #, chyba że przejdziesz przez interfejs Reflection.
Wczesne wiązanie oznacza po prostu, że metoda docelowa zostanie znaleziona w czasie kompilacji i zostanie utworzony kod, który to wywoła. Niezależnie od tego, czy jest wirtualny, czy nie (co oznacza, że jest dodatkowy krok, aby go znaleźć w czasie rozmowy, nie ma znaczenia). Jeśli metoda nie istnieje, kompilator nie skompiluje kodu.
Późne wiązanie oznacza, że metoda docelowa jest sprawdzana w czasie wykonywania. Często do jej wyszukiwania używana jest tekstowa nazwa metody. Jeśli metody nie ma, bum. Program ulegnie awarii lub przejdzie do jakiegoś schematu obsługi wyjątków w czasie wykonywania.
Większość języków skryptowych używa późnego wiązania, a języki kompilowane używają wczesnego wiązania.
C # (przed wersją 4) nie wiąże się z opóźnieniem; mogą jednak użyć do tego interfejsu API odbicia. Ten interfejs API kompiluje się do kodu, który wyszukuje nazwy funkcji, przeszukując zestawy w czasie wykonywania. VB może późno wiązać, jeśli opcja Strict jest wyłączona.
Wiązanie zwykle wpływa na wydajność. Ponieważ późne wiązanie wymaga wyszukiwania w czasie wykonywania, zwykle oznacza to, że wywołania metod są wolniejsze niż wywołania metod z wczesnym wiązaniem.
W przypadku normalnej funkcji kompilator może obliczyć numeryczne położenie jej w pamięci. Następnie, gdy funkcja jest wywoływana, może wygenerować instrukcję wywołania funkcji pod tym adresem.
Dla obiektu, który ma jakiekolwiek metody wirtualne, kompilator wygeneruje tabelę v-table. Zasadniczo jest to tablica zawierająca adresy metod wirtualnych. Każdy obiekt, który ma metodę wirtualną, będzie zawierał ukryty element członkowski wygenerowany przez kompilator, który jest adresem tabeli v-table. Kiedy wywoływana jest funkcja wirtualna, kompilator ustala, jaka jest pozycja odpowiedniej metody w tabeli v. Następnie wygeneruje kod, który zajrzy do obiektów v-table i wywoła metodę wirtualną w tej pozycji.
Tak więc występuje wyszukiwanie, które występuje dla funkcji wirtualnej. Jest to mocno zoptymalizowane, więc nastąpi to bardzo szybko w czasie wykonywania.
Wczesne wiązanie
- Kompilator może ustalić, gdzie wywoływana funkcja będzie w czasie kompilacji.
- Kompilator może zagwarantować wcześnie (przed uruchomieniem kodu programu), że funkcja będzie istnieć i będzie można ją wywołać w czasie wykonywania.
- Kompilator gwarantuje, że funkcja przyjmuje odpowiednią liczbę argumentów i że są one odpowiedniego typu. Sprawdza również, czy zwracana wartość jest poprawnego typu.
Późne wiązanie
- Wyszukiwanie potrwa dłużej, ponieważ nie jest to proste obliczenie przesunięcia, zwykle należy dokonać porównań tekstu.
- Funkcja docelowa może nie istnieć.
- Funkcja docelowa może nie akceptować przekazanych do niej argumentów i może zwracać wartość niewłaściwego typu.
- W przypadku niektórych implementacji metoda docelowa może faktycznie ulec zmianie w czasie wykonywania. Tak więc wyszukiwanie może wykonać inną funkcję. Myślę, że dzieje się to w języku Ruby, możesz zdefiniować nową metodę na obiekcie, gdy program jest uruchomiony. Późne wiązanie umożliwia wywołaniom funkcji rozpoczęcie wywoływania nowego zastąpienia metody zamiast wywoływania istniejącej metody podstawowej.