Dlaczego C # ma zarówno out, jak i ref?

18

C # ma słowa kluczowe outi ref. Dlaczego te dwa są wymagane? Oświadczenie: Nie mam głębokiej wiedzy na temat C #.

Neo
źródło
3
Czy w przepełnieniu stosu nie ma duplikatu między witrynami?
Peter Mortensen
6
Kandydat: Dlaczego C # rozróżnia ref i out?
Peter Mortensen
2
Czy pytasz o różnicę między refi out? A może pytasz, jakie jest użycie argumentów ref/ referencji outw porównaniu do argumentów według wartości (bez modyfikatora parametru)? Lub oba?
Jeppe Stig Nielsen
1
Wydaje

Odpowiedzi:

32

Jeśli chodzi o implementację, są one zasadniczo takie same, ale outkomunikują coś, czego refnie ma: nie przejmujesz się wkładem. Oznacza to pewne rzeczy dla Ciebie i dla narzędzi. Na przykład, możesz przekazać niezainicjowaną zmienną do outparametru i to nie jest problem, w innym przypadku byłoby to możliwe, aw ramach funkcji musisz przypisać wartość do outparametru przed jego zwróceniem, podczas gdy nie ma potrzeby robienia czegokolwiek w parametrze wszystko z refwartością.

Mason Wheeler
źródło
10
Ref vs out jest o wiele ważniejsze dla kompilatora niż dla programisty. Kompilator jest zobowiązany do upewnienia się, że nie odczytujesz zmiennej, zanim zostanie mu przypisana wartość, i outdaje sposób, aby to lepiej pasowało do tego, jak chcesz sobie radzić ze zmiennymi.
Cort Ammon - Przywróć Monikę
Czy możesz rozwinąć temat: „out” komunikuje coś, czego „ref” nie ma.
Neo
4
@Neo: Zasadniczo to, co powiedziałem w odpowiedzi: Komunikat mówi, że nie obchodzi cię to, że używasz tego do wprowadzania danych, a zatem bezpiecznie jest przekazać niezainicjowaną wartość do outparametru, ponieważ funkcja odbierająca go nie będzie z niego czytać .
Mason Wheeler,
@MasonWheeler Czy jest to jednak dozwolone (i / lub egzekwowane po stronie odbierającej) przez weryfikatora? Out jest tylko wewnętrznie atrybutem.
Random832
@ Random832: Jak Robert napisał pod swoją odpowiedzią, spójrz na Erica Lipperta (byłego kompilatora C #) omawiającego to na stackoverflow.com/q/2876315
Mason Wheeler
7

Aby zrozumieć te dwa słowa kluczowe, musisz zrozumieć, co oznacza przekazanie wartości przez odwołanie . Zasadniczo oznacza to, że jeśli zmodyfikujesz zmienną parametru przekazywaną w ramach metody lub funkcji, zmienna ta zachowuje swoją zmodyfikowaną wartość po wyjściu z funkcji. Zadeklarowanie parametru jako takiego reflub outdokonanie tego, podczas gdy zwykła zmienna parametru zachowałaby swoją pierwotną wartość, nawet jeśli zmodyfikujesz go w funkcji.

Jedyne różnice między refi outto, że outnie wymaga inicjalizacji zmiennej przed przekazaniem jej do funkcji, ale refwymaga; natomiast out nie wymaga, aby przypisać coś do zmiennej wewnątrz funkcji, ale reftego nie robi.

Robert Harvey
źródło
Czy nie ma różnicy związanej z wariancją?
monocell
Zobacz odpowiedź Erica Lipperta na stackoverflow.com/q/2876315
Robert Harvey
2

Zapytałeś.

C # ma obecnie i ref, dlaczego te dwa są wymagane. Nie mam głębokiej wiedzy na temat C #. Dlaczego wymagane są parametry out i ref?

I odpowiedź jest taka, że ​​nie są WYMAGANE, java na przykład nie ma żadnego, a VB ma tylko ref (i wymaga go tylko w deklaracji metody).

Możesz łatwo napisać cały program bez użycia żadnego z nich.

Istnieją, ponieważ czasami są przydatne. Dlatego są ich dwa, a nie tylko jeden - ponieważ warto rozróżnić „tu jest coś, zmodyfikuj go, jeśli chcesz” i „nadaj temu rzeczowi nową wartość”.

Inne języki mają różne priorytety, więc mogą, ale nie muszą, uwzględniać te lub równoważne. Mogą nawet nie zgadzać się co do tego, czy któreś z nich jest przydatne, i dlatego mogą aktywnie decydować o NIE wdrażaniu jednego lub drugiego.

jmoreno
źródło
1

Zarówno w ich rdzeniu refi outzapewnić mechanizm przekazywania adresu zmiennej do metody tak, że może być aktualizowana - przypisanie do reflub outparametr aktualizuje zmienną w kontekście rozmówcy. Różnią się one gwarancjami: outgwarancje, że zmienna zostanie zaktualizowana, refnie.

Z drugiej strony połączenia występują podobne różnice. Nie outmożna zagwarantować, że parametr naszej metody zawiera coś użytecznego po przybyciu i musi być ustawiony na wartość w pewnym momencie, podczas gdy refmożna założyć , że parametr ma wartość i nie musimy robić z nią nic konkretnego.

Różnica ta ma wpływ na analizę, generowanie i optymalizację kodu, która - choć nie jest nam to przez większość czasu szczególnie widoczna - może mieć wpływ na sposób działania naszych programów. Generator kodu może odroczyć alokację zmiennej do momentu bezpośrednio przed wywołaniem, optymalizator może zdecydować, że może bardziej skutecznie porządkować niektóre operacje na podstawie umowy itp.

Pod względem użytkowania: jako ogólna zasada stosuję outw sytuacjach, w których nie dbam o treść zmiennej, gdy pojawia się ona jako parametr i refkiedy to robię.

Corey
źródło