C # oferuje ref
i out
słów kluczowych, aby argumenty mają być przekazywane przez referencję. Semantyka tych dwóch jest bardzo podobna. Jedyną różnicą jest inicjalizacja zmiennej flaged:
ref
wymaga zainicjowania zmiennej przed przekazaniem jej do funkcji,out
nie.out
wymaga inicjalizacji zmiennej wewnątrz funkcji,ref
nie wymaga.
Przypadki użycia tych dwóch słów kluczowych są również prawie takie same, a ich zbyt częste użycie uważam za zapach kodu (chociaż istnieją prawidłowe przypadki użycia, takie jak TryParse
i TryGetValue
wzorce).
Z tego powodu ktoś mógłby wyjaśnić, dlaczego istnieją dwa bardzo podobne narzędzia w języku C # dla tak wąskich przypadków użycia?
Ponadto w witrynie MSDN stwierdzono, że mają one różne zachowanie w czasie wykonywania:
Chociaż słowa kluczowe ref i out powodują różne zachowanie w czasie wykonywania, nie są one uważane za część podpisu metody w czasie kompilacji.
Czym różni się ich zachowanie w czasie wykonywania?
Wniosek
Obie odpowiedzi wyglądają poprawnie, dziękuję wam obojgu. Zaakceptowałem jmoreno , ponieważ jest bardziej jednoznaczne.
źródło
ref
w C ++; do wskaźników do wskazanego wskaźnika obiektu (lub prymitywu). tj.Int32.TryParse(myStr, out myInt)
(C #) jest „wykonywany” w taki sam sposób, jakint32_tryParse(myStr, &myInt)
zrobiłby to (C); jedyną różnicą są pewne ograniczenia narzucone przez kompilator w celu zapobiegania błędom. (Nie opublikuję tego jako odpowiedzi, ponieważ mogę się mylić co do tego, jak to działa za kulisami, ale tak sobie wyobrażam, że to działa [ponieważ ma to sens])Odpowiedzi:
W momencie zadawania tego pytania artykuł MSDN był subtelnie niepoprawny ( od tego czasu został poprawiony ). Zamiast „powodować inne zachowanie” powinno być „wymaga innego zachowania”.
W szczególności kompilator wymusza różne wymagania dla dwóch słów kluczowych, nawet jeśli ten sam mechanizm (IL) jest używany do włączenia tego zachowania.
źródło
out
parametru lub nieprzypisanieref
parametru, ale IL, którą emituje, jest tylko odniesieniem w obu przypadkach. Czy to jest poprawne?out T
iref T
te są wykonywane identycznie w innych językach, takich jak CLI VB.Net lub C ++ / CLI.oto ciekawy opis na ten temat, który może odpowiedzieć na twoje pytanie:
http://www.dotnetperls.com/ref
punkt zainteresowania:
„Różnica między ref i out nie jest w środowisku uruchomieniowym Common Language, ale w samym języku C #”.
aktualizacja:
starszy programista w mojej pracy właśnie potwierdził odpowiedź @ jmoreno, więc przeczytaj ją!
źródło
string
ma wspólnego z tym wszystkim?Runtime ? Absolutnie żaden. Nie można przeciążać metody o tych samych parametrach, różniących się tylko słowem kluczowym ref lub out.
Spróbuj to skompilować, a pojawi się błąd kompilacji „Metoda z tą samą sygnaturą jest już zadeklarowana”:
Aby odpowiedzieć na to pytanie: „... dlaczego są dwa bardzo podobne narzędzia w C # dla tak wąskich przypadków użycia?”
Z punktu widzenia czytelności kodu i API istnieje ogromna różnica. Jako konsument interfejsu API wiem, że kiedy używane jest „wyjście”, API nie zależy od parametru wyjścia. Jako programista API wolę „out” i używam „ref” tylko wtedy, gdy jest to absolutnie (RZADKO!) Konieczne. Świetna dyskusja znajduje się w tym dokumencie:
/programming/1516876/when-to-use-ref-vs-out
Informacje dodatkowe: skompilowałem następującą metodę i ją zdemontowałem. Użyłem słów kluczowych ref i out (out w tym przykładzie), ale kod zestawu nie zmienił się, z wyjątkiem odwołania do adresu, jak się spodziewałbym:
00000000 push ebp
00000001 mov ebp, esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp, 34h
00000009 xor eax, eax
0000000b mov dword ptr [ebp-10h], eax
0000000e mov dword ptr [ebp-
00C] mov dword ptr [ebp-3Ch], ecx
00000014 mov dword ptr [ebp-40h], edx
00000017 cmp dword ptr ds: [008B1710h], 0
0000001e je 00000025
00000020 połączenie 6E6B601E
00000025 nop
param = 0;
00000026 mov eax, dword ptr [ebp-40h]
00000029 xor edx, edx
0000002b mov dword ptr [eax], edx
}
0000002d nop
0000002e lea esp, [ebp-0Ch]
00000031 pop ebx
00000032 pop esi
00000033 pop edi
00000034 pop ebp
00000035 ret
Czy poprawnie czytam zestaw?
źródło