簡體   English   中英

如何在實際需要之前初始化C#靜態類?

[英]How to initialize a C# static class before it is actually needed?

我有一個帶有靜態構造函數的靜態類,需要花費一些時間(10-15秒)來執行並完全初始化類。 為了提高性能,我決定將這個靜態類顯式初始化,而不是在第一次需要它時,以便在實際需要使用時准備好。

我的第一個想法是為類創建一個Initialize()方法,但由於我已經有了一個靜態構造函數,這個方法似乎不需要做任何事情,除了是調用顯式初始化類而不訪問任何類的方法其他公共方法或財產。 擁有一種不直接做任何事情的方法對我來說似乎並不合適。

然后我想我可以將代碼從靜態構造函數移動到這個Initialize()方法中,但是我還希望在首次需要時初始化類並且沒有顯式調用Initialize()方法。

總而言之,我希望遵守以下標准:

  • 我想允許顯式初始化靜態類(可能通過使用公共Initialize()方法)。
  • 我不想在不需要它時訪問類上的任何其他公共方法或屬性,即使這會初始化靜態類。
  • 如果該類尚未顯式初始化,我仍然希望在首次需要時初始化它(即訪問其他公共方法或屬性時,意圖使用它們提供的功能或數據)。
  • 這是一個幫助類,使用Singleton設計模式對我來說不是必需的。

對於用C#編寫的靜態類,遵循上述標准的正確方法是什么? 這也適用於其他編程語言(例如Java),但我個人對使用C#編寫的解決方案感興趣。

我會使用初始化方法(編輯:請參閱Jon的答案)。 但是如果你真的只想使用構造函數,你可以這樣做:

var type = typeof (YourType);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);

RunClassConstructor允許您強制類構造函數(靜態構造函數)運行(如果它尚未運行)。 如果它已經運行,比如因為你使用了類的靜態成員,那么這沒有效果。 再運行一次沒有效果。

我可能只是去尋找Initialize方法 - 它可以做一些有用的事情:

  • 它可以記錄您明確嘗​​試使用堆棧跟蹤初始化類
  • 如果已經通過另一個Initialize調用初始化了類,則可能會拋出異常
  • 可能 (通過一些努力和重組)對事物進行排序,以便在初始化期間導致的任何異常都會傳播,而不會TypeInitializationException您通常會得到的TypeInitializationException

兩種解決方法:

  1. 將構造函數代碼移動到Initialize()以便可以顯式調用。 並且在構造函數內部的代碼替換為只調用Initialize()方法,以防靜態類在您明確調用它之前動態加載

     public static class StaticClass { // actual constructor static StaticClass() { Initialize(); } // explicit "constructor" public static void Initialize() { MyProperty = "Some Value"; } public static string MyProperty { get; set; } } 

    如果你想要,那么初始化如下:

     StaticClass.Initialize(); 

    或者它會在第一次使用時動態初始化

  2. 不像語義上那樣原始,但是你可以通過使用屬性並將其拋入臨時變量來觸發靜態類的有機初始化。

    所以這樣做:

     // trigger static initilaization var dummy = StaticClass.MyProperty; 

    仍然允許您在需要時調用它,但如果在初始化時有一些性能成本,您可以嘗試在啟動時調用它,而不是在用戶第一次執行觸發該代碼的操作時。

有關靜態初始化的另一個有用的概述,請參閱: C#中靜態類初始化的順序是否確定?

我不確定你是否可以指定何時加載靜態構造函數。

來自MSDN“在創建第一個實例或引用任何靜態成員之前,會自動調用靜態構造函數來初始化類。”

http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx

* 編輯:*添加單身模式會有幫助嗎? getter可以通過檢查類中的標志IsLoaded = true來調用Initialize()。 后續調用不會調用Initialize()

這種方法對我來說似乎並不好看。 我可能將方法命名為Touch(),給它一個空體,並添加適當的注釋。 這是否足以讓你感覺到某些事情對此感覺不正確?

暫無
暫無

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

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