我有以下代码。这不是我正在使用的确切代码,因为它是我工作地点的内部,但它代表了我遇到的情景。
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 :(得分:10)
交换_instance
和a
字段的声明。在C#中,静态字段按声明的顺序初始化。换句话说,您的Server
构造函数运行得太早。
或者您可以将a
声明为const
,这会将其从构建过程中删除。
答案 1 :(得分: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节)存在于 class,执行静态字段 初始化器紧接在之前发生 执行该静态构造函数。 否则,静态字段 初始化程序在执行时执行 依赖于实现的时间 第一次使用静态场 那个班。
我不确定我会使用那种......它太容易破碎。
你能把它改成const吗?那会更强大:
private const string a = @"D:\test.txt";
这样,如果有人在以后再次更改订单,并认为重新排序是无害的操作,则无关紧要。据推测,你不知道订单在这里的重要性,否则你不会问这个问题 - 你是否愿意赌博另一个看同一代码的程序员不会有同样的问题? :)
答案 2 :(得分:1)
静态字段按它们在文本文件中出现的顺序进行实例化。因此,在字符串初始化之前,您的服务正在构建。如果你交换这两行,它应该有用。
链接:http://msdn.microsoft.com/en-us/library/aa645758%28VS.71%29.aspx
哦,单身模式通常是一种反模式。尽可能避免使用它。