2012-08-30 9 views
9

Powiel możliwe:
Can I change a private readonly field in C# using reflection?Ustawienie pola readonly (Czy to bug?)

gdy tylko gra z C#, realizowany dziwną rzecz.

oto kod:

class Program 
{ 
    static void Main(string[] args) 
    { 
     System.Diagnostics.Debug.Write(string.Empty); 

     typeof(string) 
      .GetField("Empty", BindingFlags.Static | BindingFlags.Public) 
      .SetValue(null, "Tolgahan"); 


     Console.WriteLine(string.Empty); 

     // output : Tolgahan 
    } 
} 

Dlaczego refleksja pozwala nam na zmianę pola tylko do odczytu?

AKTUALIZACJA: Pytanie brzmiało "dlaczego ustawienie poprzez odbicie jest dozwolone", a nie "jak to zrobić", więc nie jest duplikatem.

+4

Możesz robić różne rzeczy z refleksją, której normalnie nie możesz zrobić. Na przykład możesz uzyskać/ustawić prywatne pola z innych klas. Jestem niemal pewien, że to nie jest błąd; co do tego, czy jest to pożądane, czy inna historia. – Servy

+3

Aby ukraść cytat, tylko do odczytu jest ochrona przed "Murphy, a nie Machiavelli" –

+0

@Dennis: Inne pytanie tylko pyta, czy jest to możliwe, ten mówi, że jest to możliwe, ale pyta dlaczego (i dlatego jest IMO o wiele bardziej wartościowy niż inny). –

Odpowiedz

14

W ten sam sposób prawa chemii mówią, że żadna reakcja nie może spowodować, że atom jednego elementu zamieni się w atom innego pierwiastka, ale prawa fizyki mówią, że zdarza się to cały czas. Chemia jest ograniczonym podzbiorem fizyki, aby uprościć problemy w bardziej rozwiązywalny sposób.

Odbicie to fizyka w tym przypadku, gdzie normalnym programowaniem jest chemia. Działa w prostszy sposób myślenia. Odbicie pozwala ominąć ten prosty zestaw zasad, ujawniając nowe procesy, ale także nowe zagrożenia.

+2

Cóż za dziwaczna metafora. Nie, jego błąd nie wystarczy, czy też jest to zbyt chemiczne? – Jodrell

+3

Spróbuj przeczytać to w głosie Bryana Cranstona, nagle zaczyna mieć sens. –

+0

@ssg Więcej sensu niż Aarona Paula, przynajmniej :-) – corsiKa

0

Jest to możliwe, ponieważ Reflection w .Net został zaimplementowany w ten sposób. Mogę się tylko domyślać motywacji, ale jest to potężne (ale wolne) narzędzie, które oferuje dużą elastyczność i możliwość niewłaściwego użycia.

Nie jest to jedyny sposób, w jaki można wprowadzić taką zmianę, ale takie dyskusje są nie na temat i nie na miejscu, jak każda inna subiektywna spekulacja.

3

Ponieważ readonly, jak private, chroni przed Murphy, a nie Machiavelli *.

Używamy readonly i i wszystkiego, co ogranicza to, co możemy zrobić, głównie dlatego, że mamy nadzieję ograniczyć bardziej niepoprawne, niekonsekwentne lub po prostu głupie rzeczy, niż mamy przydatne i owocne rzeczy.

Ale wciąż jest to tylko zero. Jeśli część pamięci jest ustawiona na liczbę "42", a my uzyskujemy dostęp do niej przez pole tylko do odczytu, to nie była ona tylko do odczytu podczas tworzenia obiektu. Nic nie powstrzyma go przed zmianą, chyba że kompilator dostrzeże "hej, najpierw powiedziałeś, że nie chcesz tego zmienić, teraz próbujesz to zmienić, co daje? Jedna z tych dwóch decyzji musi być zła".

Nie ma obietnicy, że refleks będzie w stanie to zmienić, ale nie ma obietnicy, że tak się nie stanie. Teraz sposób, w jaki działa odbicie i sposób działania w trybie tylko do odczytu, oznacza, że ​​możesz go zmienić. Przynajmniej wymagałoby to wiele pracy (być może z kosztami, które wpływają na nas, użytkowników, a także zespół, który musi wdrożyć tę pracę), aby powstrzymać kogoś, kto prawdopodobnie poszedłby na ten problem, ponieważ sądzili, że dobry powód.

Należy pamiętać, że uprawnienia odnoszące się do refleksji zrobić zatrzymać Machiavellego,

* Ściśle Murphy mówi o dokładnie jak należy projektować rzeczy, aby powstrzymać ludzi przypadkowo Uprawiając katastrofalnego - readonly jest dobrym przykładem, korki, które mogą” • Fizycznie lepiej podłączyć w niewłaściwy sposób - a Machiavelli uczył, zamiast ćwiczyć techniki.To sprawia, że ​​nawet w przybliżeniu nie jest to tak zwięzłe powiedzenie.

+0

+1 Bardzo podoba mi się ta metafora. –

+0

@ p.s..g.g z Murphy i Machiavelli? Nie mogę ubiegać się o kredyt. Najwcześniejsze porównywalne użycie (o 'private' w C++) wiem o Bjarne Stroustrup, chociaż nie wiem, czy był pierwszy. –