2013-06-05 55 views
1

我的一些全局變量只需要啓動一次。我通過加載文件並將其設置爲任何內容來完成。現在我希望當我嘗試爲引發異常的變量設置一個新值時。C# - 標記變量爲常量(只讀)

public class Foo 
{ 
    public static int MIN; 

    private static loadConstants() 
    { 
     MIN = 18; 
    } 

    public static void Main() 
    { 
     loadConstants(); 
     MIN = 15; // this must throw an exception 
     // edit: at least mustn't set the new value 
    } 
} 

我該怎麼做?

(可能是很容易的,我很抱歉)

+0

「這必須拋出一個異常」 - 你真的需要它來編譯,而不是失敗,直到運行時?到目前爲止你的答案可以確保'MIN = 15;'行甚至不會編譯,所以它也不會拋出異常。 – hvd

+0

TS可能並不意味着他希望有一行存在拋出異常的情況,只是該行不會將常量MIN設置爲某個值。 – SamiHuutoniemi

+0

是的,例外是不需要的。只有唯一的價值在運行時必須堅持。 – Bitterblue

回答

6

創建一個靜態構造函數,並標記變量只讀。然後在構造函數中設置該值。

public static class Foo 
{ 
    public static readonly int MIN; 

    static Foo() 
    { 
     MIN = 18; 
    } 

    public static void Main() 
    { 

    } 
} 
+0

好吧,我也試圖用反射破解變量。我可以設定一個新的價值。這可以以某種方式避免,而不會使變量的單行聲明覆雜化? – Bitterblue

3
public class Foo 
{ 
    public readonly static int MIN; 

    static Foo() 
    { 
     MIN = 18; 
    } 

    public static void Main() 
    { 
    } 
} 
+0

這比在運行時拋出異常好得多,如果你試圖修改它。這樣做意味着編譯器不會讓你在靜態ctor中修改它。 –

+1

OP提到,他實際上是「加載文件」而不是簡單的「MIN = 18」。我強烈建議不要在靜態類型構造函數中執行任何文件I/O。或者任何複雜的邏輯。在調試時它們是一個真正的痛苦,它很難控制執行時的確切時間。 – Imi

+0

@Imi是的,我知道,我已經完成了。謝謝! – Bitterblue

0

不是有一個公共的成員變量,您可以創建一個公共屬性,然後在你的執行管理CONST邏輯。

private static int? _min; 

public static int MIN 
{ 
    set { 
      if (!_min.HasValue()) 
      { 
       _min = value; 
      } 
      else 
      { 
       throw; 
      } 
    } 

    get { 
      return _min.ValueOrDefault(); 
    } 

} 
+0

這會在我的應用程序中沉重,因爲我已經有大約100個。 – Bitterblue

2

如果您不能或不想竟在初始化變量之前還是因爲你知道,因爲你有很多事情要做的類型使用靜態構造函數從其他的答案(例如靜態構造函數是一個真正的痛苦調試..)你可以到其他事情:


一個編譯時的解決辦法是包變量在自己的類型爲非靜態只讀並持有的靜態引用這種類型

public class Constants 
{ 
    public readonly int MIN; 
    public Constants() { MIN = 18; } 
} 
public class Foo 
{ 
    public static Constants GlobalConstants { get; private set; } 

    public static void Main() 
    { 
     // do lots of stuff 
     GlobalConstants = new GlobalConstants(); 
    } 
} 

或者你可以將常數變成一個屬性,只爲你的班級以外的任何人提供getter。請注意,聲明類將仍然可以更改屬性。

public class Foo 
{ 
    public static int MIN { get; private set; } } 

    public static void Main() 
    { 
     MIN = 18; 
     MIN = 23; // this will still work :(
    } 
} 

或者 - 如果出於某種奇怪的原因 - 你真的想要一個例外,而不是編譯錯誤,你可以做一個財產取出常量和扔你的異常的制定者。

public class Foo 
{ 
    static int _min; 
    public static int MIN { get { return _min; } set { throw new NotSupportedException(); } } 

    public static void Main() 
    { 
     _min = 18; 
    } 
} 
+0

Getter,而不是第二個代碼塊之前的文本中的setter。 – SamiHuutoniemi

+0

謝謝,修正。 ;) – Imi