Strona główna
 

[ Pobierz całość w formacie PDF ]

i dostarczane przez wywołujący kod za pośrednictwem argumentów rzeczywistych (dalej
nazywanych po prostu argumentami). Metody mają także pojedynczy wyjściowy parametr
zwrotny, który jest opcjonalny; jeśli metoda nie zwraca żadnej wartości, określa się to za
pomocą typu void. Parametr zwrotny pozwala przekazać informacje z powrotem do wywo-
łującego kodu po zakończeniu działania metody. CTS obsługuje też parametry przekazywane
przez referencję, które pozwalają wywołującemu i wywoływanemu na współdzielenie tych
samych danych. Kilka akapitów niżej wyjaśnię, jak wykorzystać wszystkie te funkcje.
Poniższy kod definiuje metodę Add, która przyjmuje dwa parametry i zwraca wartość:
class Calculator
{
public int Add(int x, int y)
{
return x + y;
}
}
Metodę tę można wywołać z kodu użytkownika, na przykład w następujący sposób:
Calculator calc = new Calculator();
int sum = calc.Add(3, 5);
Wygenerowany kod IL będzie zawierał wywołanie metody Add obiektu calc. Wartości 3 i 5
są przekazywane jako argumenty odpowiadające parametrom, odpowiednio x i y w pojedynczej
ramce aktywacji metody Add. Metoda następnie wykorzystuje dynamiczne wartości 3 i 5
z ramki aktywacji, dodając je do siebie i zwracając wynik. Ramka jest następnie zdejmowana,
a do kodu wywołującego przekazywana jest wartość 8; w tym przypadku kod zapisuje ją
w lokalnej zmiennej sum.
Metody, tak jak wszystkie inne składowe, mogą być instancyjne lub statyczne. Metody in-
stancyjne mają dostęp do specjalnego wskaznika this (nazywanego this w C#, a Me w VB)
odnoszącego się do instancji, na której wywołano metodę. Za jego pomocą mogą uzyskać
dostęp do publicznych, chronionych i prywatnych składowych instancyjnych typu (oraz
publicznych i chronionych składowych w hierarchii typu). Rozważmy na przykład klasę
z instancyjną składową state:
class Example
{
int state;
public void Foo()
{
state++;
this.state++;
}
}
Zauważmy, że C# dedukuje kwalifikację this w odwołaniu do pola state, ponieważ wy-
krywa, że w zasięgu znajduje się zmienna instancyjna. C# obsługuje też jawną kwalifikację
za pomocą słowa kluczowego this. W obu przypadkach w wygenerowanym IL zostanie to
zakodowane przez wczytanie zerowego argumentu ramki aktywacji. Jest to konwencja prze-
kazywania wskaznika this od wywołującego do metody instancyjnej. Wszystkie rzeczywiste
argumenty zaczynają się od pozycji pierwszej.

54 Część I Podstawowe informacje o CLR
Metody statyczne nie mają natomiast wskaznika this. Mają dostęp do prywatnych składo-
wych statycznych typu, ale nie otrzymują aktywnej instancji, która pozwoliłaby im na dostęp
do składowych instancyjnych. Argumenty metod statycznych zaczynają się od pozycji zerowej.
Jest to całkowicie niewidoczne na poziomie języka C#, ale na poziomie IL trzeba uwzględ-
niać tę różnicę.
Zmienne lokalne
Ramka aktywacji metody może zawierać dwa rodzaje danych lokalnych: argumenty i zmienne
lokalne. Są one przechowywane na fizycznym stosie; są przydzielane w momencie wywołania
metody i usuwane, kiedy metoda kończy działanie (wskutek powrotu albo nieobsłużonego
błędu). Omówiliśmy już użycie argumentów. Argumenty to lokacje, do których wywołujący
kopiuje dane przekazywane wywoływanemu. Pózniej zbadamy różne style przekazywania
argumentów, które  w zależności od scenariusza  mogą obejmować kopiowanie wartości
albo przekazywanie referencji do lokalnych struktur danych wywołującego.
Metoda może też używać zmiennych lokalnych. Są one również alokowane na stosie, ale
całkowicie niewidoczne dla wywołujących; stanowią szczegół implementacyjny metody.
Podczas przydzielania miejsca na stosie zmienne lokalne są inicjalizowane przez zerowanie
(co daje 0 dla wartości skalarnych, 0.0 dla wartości zmiennopozycyjnych, false dla wartości
logicznych i null dla referencji), a każda z nich otrzymuje koncepcyjny slot. Sloty są typizo-
wane, aby CLR mogło przydzielić odpowiednią ilość miejsca, a weryfikator sprawdzić, czy
zmienne lokalne są używane w sposób bezpieczny typologicznie.
Oto przykład:
class Example
{
public void Foo()
{
int x = 0;
double y = 5.5;
string s = "Witaj, świecie";
// &
}
}
Ten kod definiuje trzy zmienne lokalne, x, y i z, które zostają ponumerowane podczas emisji
kodu IL. Większość kompilatorów nadałaby im numery odpowiednio: 0, 1 i 2, ale kompilatory
mogą przeprowadzać optymalizacje zmieniające tę kolejność. Oczywiście, w języku C#
dodatkowe zmienne lokalne mogą być zdefiniowane w dalszej części metody (inaczej niż
w C, w którym wszystkie zmienne muszą zostać wprowadzone na początku funkcji), ale jest
to cecha specyficzna dla języka; każda taka zmienna zwykle otrzymuje własny slot (choć
kompilatory mogą wielokrotnie wykorzystywać te same sloty).
Przeciążanie
Typ może zawierać wiele metod o takiej samej nazwie. Metody te muszą się jednak różnić
w jakiś znaczący sposób; określa się to mianem przeciążania. Metody można przeciążać
przez definiowanie wyróżniających je parametrów. Różnice typów zwrotnych nie wystar-
czają do przeciążenia metody.

Rozdział 2. Wspólny system typów 55
Przeciążanie pozwala tworzyć metody, które działają podobnie, ale przyjmują różne typy
parametrów, co często zwiększa wygodę korzystania z klasy. Ponadto umożliwia określanie
domyślnych wartości argumentów, na przykład przez napisanie wersji, które po prostu wy-
wołują inne przeciążone wersje z odpowiednimi wartościami parametrów.
Rozważmy na przykład przeciążoną metodę Bar w poniższym typie:
class Foo
{
internal void Bar() { Bar(10); /* wartość "domyślna" */ }
internal void Bar(int x) { /* & */ }
internal void Bar(int x, int y) { /* & */ }
internal void Bar(object o) { /* & */ }
}
Kompilatory (a w przypadku języków dynamicznych również programy do póznego wią-
zania) zajmują się rozwikływaniem przeciążeń, procesem, który polega na dopasowywaniu
argumentów wywołującego do odpowiedniej wersji metody. Jest to zasadniczo wyszukiwanie
wersji najlepiej pasującej do danego zbioru argumentów. Ogólnie rzecz biorąc, kompilatory
wybierają najbardziej specyficzne dopasowanie. Jeśli dopasowanie jest niejednoznaczne albo
nie uda się znalezć pasującej wersji metody, kompilator zwykle zgłasza ostrzeżenie lub błąd.
Jeśli na przykład mamy dwie metody:
void Foo(object o);
void Foo(string s);
to poniższy kod zostanie dowiązany do metody Foo(string), ponieważ jest ona bardziej
specyficzna:
Foo("Witaj, wiązanie!");
Oczywiście, istnieją bardziej złożone przykłady, które demonstrują szczegóły procesu wią-
zania. Wystarczy jednak kilka eksperymentów, aby rozwiać ewentualne wątpliwości dotyczące
zasad wiązania w danym języku. CTS nie narzuca żadnych reguł dotyczących rozwikływania
przeciążeń, więc mogą one być różne w poszczególnych językach.
Styl przekazywania argumentów [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • alternate.pev.pl


  •  Podstrony
     : Indeks
     : Jackson Braun Lilian Kot, który...20 Kot, który przedrzeŸniał ptaki
     : Colin Forbes Tweed 20 KomĂłrka
     : Deschner Karlheinz Polityka papieska w XX wieku t.2 2. przypisy
     : dobor glosnikow do zestawu domowego
     : Dzieci cienie. WśÂ›ród ukrytych, wśÂ›ród oszustów Haddix Margaret Peterson
     : 392. Sanderson Gill Warto byśÂ‚o czekać‡
     : J.M.McDermott Psia Ziemia 01.Dzieci demonów
     : Personal Freedom
     : 43 Pan Samochodzik i Buzdygan Hetmana Mazepy Sebastian Miernicki
     : KuczyśÂ„ski Maciej Babcia robot przy kominku
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • m-jak-milosc.pev.pl
  •  . : : .
    Copyright (c) 2008 Poznając bez końca, bez końca doznajemy błogosławieństwa; wiedzieć wszystko byłoby przekleństwem. | Designed by Elegant WPT