我有一个带静态构造函数的静态类,需要一些时间(10-15秒)来执行并完全初始化类。为了提高性能,我决定启用这个静态类,而不是在第一次需要它时,以便在实际需要使用它时就可以了。
我的第一个想法是为类创建一个Initialize()
方法,但是因为我已经有了一个静态构造函数,所以除了作为调用显式初始化的方法之外,这个方法似乎不需要做任何事情。该类没有访问任何其他公共方法或属性。拥有一种不直接做任何事情的方法对我来说似乎不对。
然后我想我可以将代码从静态构造函数移动到这个Initialize()
方法中,但是我还希望在首次需要时对类进行初始化并且Initialize()
方法不是明确地叫。
总而言之,我希望遵守以下标准:
Initialize()
方法)。对于用C#编写的静态类,遵循上述标准的正确方法是什么?这也适用于其他编程语言(例如Java),但我个人对使用C#编写的解决方案感兴趣。
答案 0 :(得分:19)
我会选择初始化方法(编辑:请参阅Jon的回答)。但是,如果你真的只是想使用构造函数,你可以这样做:
var type = typeof (YourType);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
RunClassConstructor
允许您强制类构造函数(静态构造函数)运行(如果它已经没有)。如果它已经运行,比如因为你使用了类的静态成员,那么这没有效果。再运行一次没有效果。
答案 1 :(得分:15)
我可能会选择Initialize
方法 - 可以做一些有用的事情:
Initialize
调用已初始化该类,则可能会抛出异常TypeInitializationException
的情况下传播。答案 2 :(得分:2)
我不确定你是否可以指定何时加载静态构造函数。
来自MSDN “在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。”
http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx
* 编辑:* 在这里添加单例模式会有帮助吗? getter可以通过检查类中的标志IsLoaded = true来调用Initialize()。后续调用不会调用Initialize()
答案 3 :(得分:2)
Two work-arounds:
Move the constructor code to Initialize()
so you can call explicitly. And replace the code inside the constructor to just call the Initialize()
method in case the static class is loaded dynamically before you've called it explicitly
public static class StaticClass
{
// actual constructor
static StaticClass()
{
Initialize();
}
// explicit "constructor"
public static void Initialize()
{
MyProperty = "Some Value";
}
public static string MyProperty { get; set; }
}
Then initialize like this if you want:
StaticClass.Initialize();
Or it will be dynamically initialized the first time it's used
Not as semantically pristine, but you can trigger the organic initialization of a static class just by consuming a property and throwing it in a temporary variable.
So just do this:
// trigger static initilaization
var dummy = StaticClass.MyProperty;
Still allows you to call it whenever you need to, but if there is some performance cost on initialization, you can try to invoke it on startup, rather than the first time the user does something that fires that code.
For another helpful outline of static initialization see: Is the order of static class initialization in C# deterministic?
答案 4 :(得分:0)
这种做法对我来说似乎并不惹人注意。我可能将方法命名为Touch(),给它一个空体,并添加适当的注释。这足以让你感觉到某些事情对此感觉不正确吗?