私はあなたがJITによって実行されています最適化に獲物を落下していると思います。実際にはそのフィールドの値を変更できますが、何らかの理由でその変更の結果がすぐには表示されません。
typeof(Type).GetField("Delimiter", BindingFlags.Public | BindingFlags.Static).SetValue(null, '-');
Func<char> getDelimiter =() => Type.Delimiter;
Console.WriteLine(getDelimiter());
このコードは、フィールドの更新された値を確実に示してくれました。私はひどく驚いているとは言えません。フィールドは読み取り専用として宣言されるため、JITterはフィールドにアクセスするときにその前提を使用することがあります。あなたはいたずらと悪をやっている、本当にこれが正常な方法で動作することについての期待はないはずです。今
は、bool.TrueString
フィールドを変更する場合、これは現れなかった理由については、私の最高の推測では、Type.Delimiter
が値型(char
)であるのに対し、それは参照型(string
)であることbool.TrueString
によるものだということです。私はこれが異なる最適化を誘発すると想像することができます。
私はこのコードを逆アセンブルを見ました:
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
あなたはジッタがリテラル値'.'
でそれを置き換えることにより、Type.Delimiter
フィールドアクセスを離れて最適化されたことはかなりはっきりと見ることができます。 bool.TrueString
の静的フィールドアクセスは、実際のフィールドからまだロードされているようです。
わからないような
DateTime
Sまたは参照型のようなものは、とにかく恐ろしいアイデアだと思いint
、long
、およびchar
のようなものが含まれていますが、ありません。 – itsme86ソースを見ると、2つのフィールドはほぼ同じであるが、それほど多くはないと宣言されています.1つは読み取り専用= "。"、もう1つは読み取り専用=別の読み取り専用リテラルです。 – pm100
野生の推測。boolは 'struct'であり、' Type'は抽象クラスであるため、Reflectionはその構造体に黒い魔法を実行するかもしれません。私が言ったように、ちょうど推測 – lokusking