为什么我不能改变Type.Delimiter使用反射? [英] Why can't I change Type.Delimiter using Reflection?

查看:150
本文介绍了为什么我不能改变Type.Delimiter使用反射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我要改变 bool.TrueString 的价值,我会使用反射做到这一点:

If I were to change the value of bool.TrueString, I'd do it using Reflection:

typeof(bool).GetField("TrueString", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Yes");
Console.WriteLine(bool.TrueString); // Outputs "Yes"



不过,我不能设法改变,比方说值, Type.Delimiter

typeof(Type).GetField("Delimiter", BindingFlags.Public | BindingFlags.Static).SetValue(null, '-');
Console.WriteLine(Type.Delimiter); // Outputs "."



这是为什么?

Why is this?

推荐答案

我觉得你堕入到的正在由JIT进行优化。实际上,你可以改变字段的值,但是,出于某种原因,这种变化的结果不会立即可见。我设法做一些愚蠢的事要解决这个问题:

I think you're falling prey to an optimization that's being performed by the JIT. You actually can change the value of that field but, for some reason, the results of that change won't be immediately visible. I managed to get around that by doing something stupid:

typeof(Type).GetField("Delimiter", BindingFlags.Public | BindingFlags.Static).SetValue(null, '-');
Func<char> getDelimiter = () => Type.Delimiter;
Console.WriteLine( getDelimiter() );

此代码显示出可靠的领域,我更新的值。我不能说我非常惊讶;该字段声明为只读,所以访问该字段时,抖动可能使用的假设。你正在做一些淘气和邪恶,那里真的不应该有任何期待这在一个正常的方式工作。

This code reliably showed the updated value of the field for me. I can't say I'm terribly surprised; the field is declared as read-only, so the JITter may use that assumption when accessing the field. You're doing something naughty and evil, there shouldn't really be any expectation for this to work in a sane way.

现在,至于为什么这次没修改 bool.TrueString 字段时,展现出来,我最好的猜测是,它是由于 bool.TrueString 作为一个参考类型(字符串),而 Type.Delimiter 是值类型(字符)。我能想象这引发不同的优化。

Now, as for why this didn't show up when modifying the bool.TrueString field, my best guess is that it's due to bool.TrueString being a reference type (string) whereas Type.Delimiter is a value type (char). I could imagine this triggering different optimizations.

我没看反汇编此代码:

        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 静态字段访问似乎仍然从实际现场加载。

You can see pretty clearly that the JITter optimized away the Type.Delimiter field access by replacing it with the literal value '.'. The static field access for bool.TrueString still appear to load from the actual field.

这篇关于为什么我不能改变Type.Delimiter使用反射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆