Spróbuję swoich sił w wyjaśnieniu:
Myślę, że rozumiemy, w jaki sposób typy wartości działają prawidłowo? Typy wartości to (int, long, struct itp.). Kiedy wyślesz je do funkcji bez polecenia ref, KOPIUJE dane . Cokolwiek zrobisz z tymi danymi w funkcji, wpływa tylko na kopię, a nie na oryginał. Polecenie ref wysyła dane RZECZYWISTE, a wszelkie zmiany wpłyną na dane poza funkcją.
Przejdź do mylącej części, typy referencji:
Utwórzmy typ referencyjny:
List<string> someobject = new List<string>()
Kiedy odkrywasz jakiś obiekt , tworzone są dwie części:
- Blok pamięci przechowujący dane dla niektórych obiektów .
- Odwołanie (wskaźnik) do tego bloku danych.
Teraz, gdy wysyłasz jakiś obiekt do metody bez odwołania , KOPIUJ wskaźnik odniesienia , a NIE dane. Więc teraz masz to:
(outside method) reference1 => someobject
(inside method) reference2 => someobject
Dwa odniesienia do tego samego obiektu. Jeśli zmodyfikujesz właściwość na jakimś obiekcie za pomocą referencji2, wpłynie to na te same dane, na które wskazuje referencja1.
(inside method) reference2.Add("SomeString");
(outside method) reference1[0] == "SomeString" //this is true
Jeśli wyzerujesz referencję2 lub wskażesz nowe dane, nie wpłynie to na referencję1 ani na referencję danych1.
(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true
The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject
Co się stanie, gdy wyślesz jakiś obiekt przez odwołanie do metody? Rzeczywiste odniesienie do someObject zostanie wysłany do metody. Masz teraz tylko jedno odniesienie do danych:
(outside method) reference1 => someobject;
(inside method) reference1 => someobject;
Ale co to znaczy? Działa dokładnie tak samo, jak wysyłanie jakiegoś obiektu nie przez referencję, z wyjątkiem dwóch głównych rzeczy:
1) Kiedy zerujesz referencję w metodzie, zeruje ona referencję spoza metody.
(inside method) reference1 = null;
(outside method) reference1 == null; //true
2) Możesz teraz wskazać odwołanie do zupełnie innej lokalizacji danych, a odwołanie poza funkcją będzie teraz wskazywać nową lokalizację danych.
(inside method) reference1 = new List<string>();
(outside method) reference1.Count == 0; //this is true
MyClass
że będzie toclass
typ, tj. Typ referencyjny. W takim przypadku przekazany obiekt można zmodyfikować zamyFunction
pomocą słowa kluczowego parzyste bezref
/ /out
.myFunction
otrzyma nowe odniesienie, które wskazuje na ten sam obiekt, i może modyfikować ten sam obiekt, ile chce. Różnicaref
spowodowałaby, że słowo kluczowemyFunction
otrzymałoby to samo odwołanie do tego samego obiektu. Byłoby to ważne tylko w przypadkumyFunction
zmiany odniesienia do punktu na inny obiekt.