为什么在通过反射更改静态只读字段后,该只读字段的输出是旧的?
Why after changing a static readonly field via reflection the output of that readonly field is old?
为什么 "someValue" 变量是只读的(但我们仍然可以通过反射更改它的值)输出为“10”,尽管它实际上已更改为 55?
static class Program
{
static readonly int someValue = 10;
static void Main(string[] args)
{
Console.WriteLine(someValue); // 10
typeof(Program)
.GetField("someValue", BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, 55); // change readonly field via reflection to 55
Console.WriteLine(someValue); // output in console 10,
// but in visual studio debugger it shows 55
Console.ReadKey();
}
}
可能只是为了防止多次读取变量而进行的 JIT 优化。
您正在更改已声明为只读的内存位置,因此如果读者缓存这些值,请不要感到惊讶。
这是JIT-compiler的优化。 JIT 内联静态只读字段。
让我解释一下。
让我们从简单的事实开始:
Static constructors are only called once in a process for each type.
因此,静态只读字段只能初始化一次,这与实例只读字段不同:
实例构造函数可以被多次调用(为了创建 class 的新实例),因此当涉及到实例只读字段时,可以有多个不同的值。您不能在方法中内联某些实例的只读字段,因为该方法可能正在使用其他实例。
When you access any type's or its instance's data or functions or whatever else, the static constructor of that type has already been called.
这意味着,在访问类型时,总是先调用静态构造函数。所以,static readonly字段一定已经被初始化了!
JIT-Compiler perfectly knows what i'm talking about above.
那么,为什么不决定在使用该静态只读字段的方法中内联它呢?
看,如果一个方法正在使用该静态只读字段,那么它正在访问该类型。如果它正在访问该类型,那么该类型的静态构造函数已经被调用,并且静态只读字段已经被初始化。静态构造函数将永远不会被再次调用,静态只读字段将具有相同的值,直到您不重新启动应用程序!如果我们知道该字段将始终具有相同的值,为什么不将其内联到方法中呢?
为什么 "someValue" 变量是只读的(但我们仍然可以通过反射更改它的值)输出为“10”,尽管它实际上已更改为 55?
static class Program
{
static readonly int someValue = 10;
static void Main(string[] args)
{
Console.WriteLine(someValue); // 10
typeof(Program)
.GetField("someValue", BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, 55); // change readonly field via reflection to 55
Console.WriteLine(someValue); // output in console 10,
// but in visual studio debugger it shows 55
Console.ReadKey();
}
}
可能只是为了防止多次读取变量而进行的 JIT 优化。
您正在更改已声明为只读的内存位置,因此如果读者缓存这些值,请不要感到惊讶。
这是JIT-compiler的优化。 JIT 内联静态只读字段。
让我解释一下。
让我们从简单的事实开始:
Static constructors are only called once in a process for each type.
因此,静态只读字段只能初始化一次,这与实例只读字段不同: 实例构造函数可以被多次调用(为了创建 class 的新实例),因此当涉及到实例只读字段时,可以有多个不同的值。您不能在方法中内联某些实例的只读字段,因为该方法可能正在使用其他实例。
When you access any type's or its instance's data or functions or whatever else, the static constructor of that type has already been called.
这意味着,在访问类型时,总是先调用静态构造函数。所以,static readonly字段一定已经被初始化了!
JIT-Compiler perfectly knows what i'm talking about above.
那么,为什么不决定在使用该静态只读字段的方法中内联它呢?
看,如果一个方法正在使用该静态只读字段,那么它正在访问该类型。如果它正在访问该类型,那么该类型的静态构造函数已经被调用,并且静态只读字段已经被初始化。静态构造函数将永远不会被再次调用,静态只读字段将具有相同的值,直到您不重新启动应用程序!如果我们知道该字段将始终具有相同的值,为什么不将其内联到方法中呢?