2009-12-03 87 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