在调试步骤中,Visual Studio 2013显示BitConverter.IsLittleEndian
是:
BitConverter
上并看到BitConverter.IsLittleEndian
和var x = BitConverter.IsLittleEndian;
我认为应该已经评估BitConverter.IsLittleEndian
,因为我在GetBytes
上调用了BitConverter
所以此时应调用静态构造函数,对吧?我错过了什么?
我的代码是这样的(我想生成顺序Guid
; rest
是long
计数器的字节 - 在此版本中):
static Guid Id(long ticks, byte[] rest)
{
var ticksBytes = BitConverter.GetBytes(ticks).PolishEndian();
// var x = BitConverter.IsLittleEndian; // <- TESTED HERE
int a = BitConverter.ToInt32(new byte[] { ticksBytes[4], ticksBytes[5], ticksBytes[6], ticksBytes[7] }.PolishEndian(), 0);
short b = BitConverter.ToInt16(new byte[] { ticksBytes[2], ticksBytes[3] }.PolishEndian(), 0);
short c = BitConverter.ToInt16(new byte[] { ticksBytes[0], ticksBytes[1] }.PolishEndian(), 0);
return new Guid(a, b, c, rest.PolishEndian(true).ToArray());
}
static byte[] PolishEndian(this byte[] ba, bool reverse = false)
{
var flag = reverse ? BitConverter.IsLittleEndian : !BitConverter.IsLittleEndian;
if (flag) return ba.Reverse().ToArray();
return ba;
}
答案 0 :(得分:2)
请注意,在这种情况下,IsLittleEndian
实际上是一个字段而不是属性。这会影响EE如何处理价值。
我在本地尝试了这个,这就是我看到的行为
首先我走了一步,直到光标碰到var ticksBytes
线。那时我观察到IsLittleEndian == false
。这实际上是在这一点上预期的。 EE并不总是需要强制运行静态构造函数才能读取字段。因此,它只是按原样读取值,因为BitConverter
没有其他代码运行值为false
在踩过那条线后,我立刻发现IsLittleEndian == true
。 CLR运行静态构造函数以执行GetBytes
方法,从而设置字段。然后EE读取设定字段。
请注意,您可以使用自己的代码重新创建此示例。例如
static class Test {
static readonly bool example;
static Test() {
example = true;
}
internal static void Go() {
// example == true
}
}
class Program {
static void Main() {
// Test.example == false;
Test.Go();
}
}
前面我提到EE并不总是需要执行静态构造函数才能读取字段。经常需要的一种情况是从通用类型读取静态字段时。在CLR实例化该类型的实例之前,不会创建泛型类型的静态字段的存储。因此,为了从尚未使用的泛型类型中读取字段,EE将在封面下创建实例以强制CLR读取它。例如
static class Test<T>
{
static readonly bool example = false;
static Test()
{
example = true;
}
}
如果将其添加到程序中,然后在监视窗口中评估以下内容
Test<int>.example
您会发现值true
清楚地表明cctor
已运行