Myślę, że padłeś ofiarą optymalizacji, która jest wykonywana przez JIT. W rzeczywistości można zmienić wartość tego pola, ale z jakiegoś powodu wyniki tej zmiany nie będą od razu widoczne. Udało mi się ominąć, że robi coś głupiego:
typeof(Type).GetField("Delimiter", BindingFlags.Public | BindingFlags.Static).SetValue(null, '-');
Func<char> getDelimiter =() => Type.Delimiter;
Console.WriteLine(getDelimiter());
Ten kod wiarygodnie pokazał zaktualizowaną wartość pola dla mnie. Nie mogę powiedzieć, że jestem strasznie zaskoczony; pole jest zadeklarowane jako tylko do odczytu, więc JITter może użyć tego założenia przy dostępie do pola. Robisz coś niegrzecznego i złego, nie powinno być żadnych oczekiwań, aby działało to w rozsądny sposób.
Teraz, dlaczego ten nie pojawił się podczas modyfikowania pola bool.TrueString
, mój najlepszy Domyślam się, że to ze względu na bool.TrueString
będąc rodzajem odniesienia (string
) natomiast Type.Delimiter
jest typ wartości (char
). Mogę sobie wyobrazić, że to powoduje różne optymalizacje.
zrobiłem spojrzeć na demontażu dla tego kodu:
Console.WriteLine(bool.TrueString);
006F2E53 8B 0D B8 10 40 03 mov ecx,dword ptr ds:[34010B8h]
006F2E59 E8 52 A6 77 54 call 54E6D4B0
Console.WriteLine(Type.Delimiter);
006F2E5E B9 2E 00 00 00 mov ecx,2Eh
006F2E63 E8 B0 FA E0 54 call 55502918
Widać dość wyraźnie, że jitter zoptymalizowany dala dostępu Type.Delimiter
pola, zastępując go z wartością dosłownym '.'
. Dostęp do pola statycznego dla bool.TrueString
nadal wydaje się być ładowany z faktycznego pola.
Nie wiem, wydaje się strasznym pomysłem. – itsme86
patrząc na źródło, dwa pola są zadeklarowane prawie tak samo, ale nie całkiem, jeden jest tylko do odczytu = ".", Drugi jest tylko do odczytu = inny literał tylko do odczytu. – pm100
Dziki domysł.Ponieważ bool jest strukturą 'struct', a' Type' jest klasą abstrakcyjną, Reflection może wykonać czarną magię na tej strukturze. Jak już powiedziałem .. tylko zgadywanie – lokusking