Widziałem tę wskazówkę w innym pytaniu i zastanawiałem się, czy ktoś mógłby mi wyjaśnić, jak to działa?
try { return x; } finally { x = null; }
Znaczy, to czy finally
klauzula naprawdę wykonać po tym return
stwierdzeniem? Jak niebezpieczny jest wątek w tym kodzie? Czy możesz pomyśleć o jakimkolwiek dodatkowym hakowaniu, który można by zrobić w przypadku tego try-finally
hacka?
c#
.net
exception-handling
Dmitri Nesteruk
źródło
źródło
Ostatecznie instrukcja jest wykonywana, ale nie ma to wpływu na wartość zwracaną. Kolejność wykonania to:
Oto krótki program pokazujący:
Wypisuje „spróbuj” (bo to jest to, co zostało zwrócone), a następnie „w końcu”, ponieważ jest to nowa wartość x.
Oczywiście, jeśli zwracamy odwołanie do zmiennego obiektu (np. StringBuilder), wówczas wszelkie zmiany dokonane w obiekcie w bloku na końcu będą widoczne po powrocie - nie wpłynęło to na samą wartość zwracaną (która jest tylko odniesienie).
źródło
return
instrukcji i ta wartość zostanie zwrócona. Wyrażenie nie jest oceniane, ponieważ kontrola opuszcza metodę.Klauzula Wreszcie jest wykonywana po instrukcji return, ale przed faktycznym powrotem z funkcji. Myślę, że nie ma to nic wspólnego z bezpieczeństwem wątków. To nie jest hack - w końcu gwarantuje się, że zawsze będzie działał bez względu na to, co robisz w bloku try lub catch.
źródło
Dodając do odpowiedzi udzielonych przez Marca Gravella i Jona Skeeta, ważne jest, aby pamiętać, że obiekty i inne typy referencji zachowują się podobnie po powrocie, ale mają pewne różnice.
Zwracane „Co” podlega tej samej logice co typy proste:
Zwracane odwołanie zostało już ocenione, zanim zmienna lokalna otrzyma nowe odwołanie w bloku na końcu.
Wykonanie jest zasadniczo:
Różnica polega na tym, że nadal można modyfikować zmienne typy przy użyciu właściwości / metod obiektu, co może spowodować nieoczekiwane zachowania, jeśli nie będziesz ostrożny.
Drugą rzeczą do rozważenia w przypadku try-return-wreszcie jest to, że parametry przekazane „przez referencję” mogą być nadal modyfikowane po powrocie. Tylko zwracana wartość została oszacowana i jest przechowywana w zmiennej tymczasowej oczekującej na zwrot , pozostałe zmienne są nadal modyfikowane w normalny sposób. Kontrakt parametru wyjściowego może nawet nie zostać wypełniony, dopóki ostatecznie nie zablokuje w ten sposób.
Jak każda inna konstrukcja przepływu, „try-return-Wreszcie” ma swoje miejsce i może pozwolić na czystszy wygląd kodu niż pisanie struktury, do której faktycznie się kompiluje. Ale należy go używać ostrożnie, aby uniknąć gotcha.
źródło
Jeśli
x
jest zmienną lokalną, nie widzę sensu, ponieważ i takx
zostanie ona ustawiona na null, gdy metoda zostanie zakończona, a wartość zwracanej wartości nie jest null (ponieważ została ona umieszczona w rejestrze przed wywołaniem setx
do zera).Widzę, że dzieje się tak tylko wtedy, gdy chcesz zagwarantować zmianę wartości pola po powrocie (i po ustaleniu wartości zwracanej).
źródło