W języku C # zawsze myślałem, że zmienne nieprymitywne były przekazywane przez referencję, a prymitywne wartości przekazywane przez wartość.
Zatem przekazując do metody dowolny nieprymitywny obiekt, wszystko, co zrobiono obiektowi w metodzie, spowodowałoby przekazanie obiektu. (C # 101 rzeczy)
Zauważyłem jednak, że kiedy mija obiekt System.Drawing.Image, wydaje się, że tak nie jest? Jeśli przekażę obiekt system.drawing.image do innej metody i załaduję obraz na ten obiekt, to pozwól tej metodzie wyjść poza zakres i wróć do metody wywołującej, czy obraz nie jest ładowany na oryginalny obiekt?
Dlaczego to?
Odpowiedzi:
Obiekty w ogóle nie są przekazywane. Domyślnie argument jest oceniany, a jego wartość przekazywana jest według wartości jako wartość początkowa parametru metody, którą wywołujesz. Ważną kwestią jest to, że wartość jest odwołaniem do typów odwołań - sposobem dotarcia do obiektu (lub wartości null). Zmiany w tym obiekcie będą widoczne dla osoby dzwoniącej. Jednak zmiana wartości parametru tak, aby odnosiła się do innego obiektu, nie będzie widoczna, gdy używasz wartości przekazywanej, która jest domyślna dla wszystkich typów.
Jeśli chcesz korzystać z funkcji przekazywania według odwołania, musisz użyć
out
lubref
, niezależnie od tego, czy typ parametru jest typem wartości, czy typem odniesienia. W takim przypadku sama zmienna jest przekazywana przez odwołanie, więc parametr używa tej samej lokalizacji pamięci co argument - a zmiany w samym parametrze są widoczne dla wywołującego.Więc:
Mam artykuł, który zawiera w tym dużo więcej szczegółów . Zasadniczo „przekazanie przez odniesienie” nie oznacza, co według ciebie oznacza.
źródło
ref
iout
od C #, to jest ok, aby powiedzieć, że C # przekazuje parametry w taki sam sposób jak Java czy to znaczy zawsze przez wartość. Czy jest jakaś różnica w java?Jeszcze jeden przykład kodu, aby to pokazać:
A wynik:
źródło
Dodano wiele dobrych odpowiedzi. Nadal chcę przyczynić się, być może wyjaśni to nieco więcej.
Gdy przekazujesz instancję jako argument do metody, przekazuje
copy
instancję. Teraz, jeśli przekazywana instancja jestvalue type
(znajduje się wstack
), przekazujesz kopię tej wartości, więc jeśli ją zmodyfikujesz, nie zostanie ona odzwierciedlona w obiekcie wywołującym. Jeśli instancja jest typem referencji, przekazujesz kopię referencji (ponownie znajduje się wstack
) do obiektu. Masz więc dwa odniesienia do tego samego obiektu. Obaj mogą modyfikować obiekt. Ale jeśli w treści metody utworzysz nowy obiekt, twoja kopia odwołania nie będzie już odnosić się do oryginalnego obiektu, będzie odnosić się do nowo utworzonego obiektu. W rezultacie będziesz mieć 2 referencje i 2 obiekty.źródło
Myślę, że jest to bardziej zrozumiałe, kiedy robisz to w ten sposób. Polecam pobranie LinqPad, aby przetestować takie rzeczy.
I to powinno dać wynik
WontUpdate
Imię: Egli, Nazwisko: Becerra
Aktualizuj niejawnie
Imię: Favio, Nazwisko: Becerra
UpdateExplicitly
Imię: Favio, Nazwisko: Becerra
źródło
Gdy przekazujesz
System.Drawing.Image
obiekt typu do metody, faktycznie przekazujesz kopię odwołania do tego obiektu.Więc jeśli w tej metodzie ładujesz nowy obraz, ładujesz za pomocą nowego / skopiowanego odwołania. Nie wprowadzasz zmian w oryginale.
źródło
Jak przekazałeś obiekt do metody?
Czy robisz nowe w tej metodzie dla obiektu? Jeśli tak, musisz użyć
ref
metody.Poniższy link daje lepszy pomysł.
http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html
źródło
W Pass By Reference dodajesz tylko „ref” do parametrów funkcji i jeszcze jedną rzecz, którą powinieneś zadeklarować jako „static”, ponieważ main jest static (#
public void main(String[] args)
)!źródło