2009-12-03 82 views
1

我有以下代碼。這不是我正在使用的確切代碼,因爲它是我的工作場所的內部,而是代表我遇到的情況。私人構造函數獲取空私有靜態只讀字符串

public class Service : ServiceBase 
{ 

    private static readonly Service _instance = new Service(); 

    private static readonly string a = @"D:\test.txt"; 

    private Service() : base() 
    { 
     // the value stored in "a" is always blank. 
     Console.Writeline(a); 
    } 

    static void Main(string[] args) 
    { 
     Run(_instance); 
    } 

} 

此代碼是一個windows服務(在基類中有服務特定的代碼)。由於某些原因,存儲在「a」中的值在構造函數中始終爲空。有沒有什麼明顯的做這件事,還是在.NET平臺上的一個怪癖?

+0

可能要重新命名您的構造函數 – PostMan 2009-12-03 23:29:28

回答

5

問題是,您在運行初始化程序a之前調用構造函數,因此您會看到a的默認值。事實上,它不是空白的(一個空字符串) - 它是null。您可以通過重新排序解決這個問題:

public class Service : ServiceBase 
{ 
    // Initialize a first 
    private static readonly string a = @"D:\test.txt"; 

    private static readonly Service _instance = new Service(); 

    ... 
} 

靜態初始化在文本順序運行(這變得有些不確定與部分類)。從部分中的C#3.0規範的10.5.5.1:一類

在靜磁場用變量初始化 對應於其中它們出現在 類聲明,其將在所述 文本順序執行 分配的序列。如果 類中存在靜態 構造函數(第10.12),則執行靜態字段 初始化器會立即發生在執行該靜態構造函數之前的 之前。 否則,靜態字段 初始化符在 執行相關時間執行 之前首先使用該類的靜態字段 。

我不確定我是否會這樣做......雖然太容易打破了。

你可以改變它爲const?這將是更穩健:

private const string a = @"D:\test.txt"; 

這樣,如果有人在日後再次改變順序,以爲重新排序也沒什麼關係是一種無害的操作。大概你不知道這裏的命令的重要性,否則你不會問這個問題 - 你有多願意賭博,看着相同代碼的另一個程序員不會有同樣的問題? :)

+0

其他人會不同意,但這是我更喜歡有一個靜態構造函數的原因。所有初始化都發生在那裏,而不是非顯而易見的。性能....等等等等等......一個像這樣的錯誤以及你「獲得」的所有perf都消失了。 nuff說。 – 2009-12-03 23:56:02

+1

在大多數情況下,靜態構造函數的性能損失很小......這是一個不錯的選擇。無論如何,我更喜歡const,但是初始化一堆非常量是個好主意。 – 2009-12-04 06:21:30

10

交換_instancea字段的聲明。在C#中,靜態字段按照聲明的順序進行初始化。換句話說,您的Server構造函數運行得太早。

或者你可以聲明aconst,從施工過程中刪除。

1

靜態字段按它們在文本文件中出現的順序進行實例化。所以你的服務在字符串初始化之前就被構造了。如果你交換這兩條線,它應該工作。

鏈接:http://msdn.microsoft.com/en-us/library/aa645758%28VS.71%29.aspx

哦,Singleton模式往往是一個反模式。儘可能避免使用它。

+0

不幸的是,這是別人的模板,我不得不合作... – Nippysaurus 2009-12-04 00:07:37