Visual Studio 2013快速监视(和静态属性)

时间:2014-02-09 20:38:09

标签: c# visual-studio debugging visual-studio-2013 static-members

在调试步骤中,Visual Studio 2013显示BitConverter.IsLittleEndian是:

  1. false:当我将鼠标悬停在BitConverter上并看到BitConverter.IsLittleEndian
  2. 的值时
  3. true:当我把它放在像var x = BitConverter.IsLittleEndian;
  4. 这样的变量中时

    我认为应该已经评估BitConverter.IsLittleEndian,因为我在GetBytes上调用了BitConverter所以此时应调用静态构造函数,对吧?我错过了什么?

    我的代码是这样的(我想生成顺序Guid; restlong计数器的字节 - 在此版本中):

    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;
    }
    

1 个答案:

答案 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已运行