2

在通過調試步驟時,Visual Studio 2013顯示BitConverter.IsLittleEndian是:的Visual Studio 2013快速監視(靜態屬性)

  1. 錯誤:當我將鼠標懸停在BitConverter鼠標和看到的BitConverter.IsLittleEndian價值和
  2. 真:當我把它放在一個變量一樣var x = BitConverter.IsLittleEndian;

我認爲BitConverter.IsLittleEndian應該已經被評估,因爲我已經在BitConverter稱爲GetBytes所以公司的S應該在這個時候調用tatic構造函數,對吧?我錯過了什麼?

我的代碼是這樣(我想生成順序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; 
} 
+0

注意在這種情況下,你正在查看一個靜態字段,而不是一個靜態屬性,它會改變一些事情。 – JaredPar

回答

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