static void ZmianaWartosci(Olowek olowek, int liczba) { // Do funkcji trafia wartość ze stosu, następnie funkcja tworzy zmienną tego samgo typu i o tej samej wartości (kopie). olowek.Grubosc = 14; liczba = 9; //Note: W tym przypadku metoda utworzy 2 kopie. }
static void PrzekazywanieZmiennychhDoFunkcji() { Olowek olowek = new Olowek(); // Do zmiennej PrzekazReferencje trafia referencja do okiektu ołówek, a nie cały obiekt. Następnie funkcja stworzy kopie obiektu na podstawie przekazanego argumentu. (wiecej niżej w ParametryRefOut()) Szuflada.PrzekazReferencje(olowek); // Note: Do funkcji zawsze trawia wartość ze stosu. }
static void ZmianaWartosci(ref Olowek olowek, ref int liczba) { // Funkcja nie tworzy kopii. olowek.Grubosc = 99; // Zmieniamy wartość na stosie. olowek = new Olowek(1); liczba = 9; //Note: Funkcja nie tworzy kopii zmiennych tylko pracuje na oryginale. }
static void KlasaSystemObject() { // Zmienna typu 'object' może przechowywać referencje do dowolnego obiektu. object obiekt; Olowek olowek = new Olowek(); obiekt = olowek; Okrag okrag = new Okrag(); obiekt = okrag; //Note: Rekomedowanie jest uzywanie aliasu 'object' zamiast System.Object tak samo jak 'string' zamiast System.String }
static void GarbageCollection() { //Garbage collection Olowek olowek = new Olowek(); Olowek grubyOlowek = new Olowek(); // Kompilator rezerwuje pamieć i przekzuje referencje do zmiennej grubyOlowek = olowek; // Nadpisujemy referencje, do poprzedniego miejsca w pamięci. Nie ma już żadnego odwołania do tej zmiennej, więc Garbage Collection odzyskuje zaalokowaną pamięc. // Garbage Collection monitoruje czy do obiektów na stercie przypisana jest referencja na stosie w czasie działania programu. Ten proces jest kosztowny czasowo-sprzętowo. // Dobrą praktyką jest aby przypisywać/kopiować referencje do zmiennej gdy nie zawiera jeszcze żadnej referencji. Olowek cienkiOlowek = null; // null jest to referencja, która nie wskazuje na żaden konkretny obiekt. if (cienkiOlowek == null) { cienkiOlowek = olowek; } }
static void ParametryRefOut() { /* Normalnie metoda tworzy kopie przekazanych argumentów bez różnicy czy argumentami są zmienne typu wartościowego czy referencyjnego. * Z modyfikatorami 'out' i 'ref' parametry funkcji stają się aliasem/przedłużeniem jej argumentu. (Metoda nie tworzy kopii zmiennych tylko pracuje na oryginale) */ /* Modyfikator 'ref' */ Olowek olowek = new Olowek(10); int liczba = 4; ZmianaWartosci(olowek, liczba); // zmienna która została przekazana do metody nazywamy argumentem. Console.WriteLine($"{olowek.Grubosc}, {liczba}"); // 14, 4 ZmianaWartosci(ref olowek, ref liczba); Console.WriteLine($"{olowek.Grubosc}, {liczba}"); // 1, 9 /* Modyfikator 'out' * Umożliwia przekazywanie zmiennych (wartosciowych lub referencycjnych) do funkcji przed ich zainicjowaniem. W takiej funkcji Musimy! przypisać wartość do tego argumentu. */ int arg; DoIncrement(out arg); Console.WriteLine($"{arg}"); // wynik '1' }