簡體   English   中英

為什么我不能改變String.Empty的值?

[英]Why can't I change the value of String.Empty?

雖然我明白改變String.Empty的值是一個壞主意,但我不明白為什么我不能這樣做。

為了得到我的意思,請考慮以下課程:

public class SomeContext 
{ 
    static SomeContext(){}
    public static readonly string Green = "Green";
    public static readonly SomeContext Instance = new SomeContext();

    private SomeContext(){}
    public readonly string Blue = "Blue";

    public static void PrintValues()
    { 
        Console.WriteLine(new { Green, Instance.Blue, String.Empty }.ToString());
    }
}

我有一個小的控制台應用程序,試圖操縱這三個只讀字段。 它可以成功地將藍色和綠色變成粉紅色,但是Empty保持不變:

        SomeContext.PrintValues();
        ///  prints out : { Green = Green, Blue = Blue, Empty = }
        typeof(SomeContext).GetField("Blue").SetValue(SomeContext.Instance, "Pink");
        typeof(SomeContext).GetField("Green", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Pink");
        typeof(String).GetField("Empty", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Pink");
        SomeContext.PrintValues();
        ///  prints out : { Green = Pink, Blue = Pink, Empty = }

為什么?

最初,我也問過為什么String.Empty不是常數。 在另一篇文章中找到了我的問題的這一部分的答案,並刪除了問題的那一部分)。

注意:沒有任何“重復”有這個問題的結論性答案,這就是我問這個問題的原因。

您無法更改它,因為您的計算機上有.NET 4.5。 只需將項目的Framework Target設置更改為3.5,您就會看到它的工作原理。

CLR具有String.Empty的內置知識。 例如,您將看到一個Reflector或Reference Source,System.String類從不初始化它。 它是在CLR啟動期間完成的。 確切地說4.5如何防止修改可見是有點難以辨別的。 實際上,你修改字段,只需添加這行代碼:

  var s = typeof(String).GetField("Empty", 
             BindingFlags.Public | BindingFlags.Static).GetValue(null);
  Console.WriteLine(s);

你會看到“粉紅色”。 我的猜測是它被抖動攔截了。 但是我無法給出確鑿的證據。 有先例,嘗試修補Decimal.MaxValue,例如,另一個只讀靜態值。 在3.5中也不可更改,抖動識別它並直接生成值而無需讀取字段。

我剛剛發現你在同一主題的另一個問題上放了一筆賞金。 280Z28的帖子非常相似。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM