正如我所知,类中的静态对象是在第一次引用类时构造的。但是我发现在程序启动时初始化静态有时很有用。是否有一些方法(即使用注释)强制执行它?
答案 0 :(得分:7)
你不能用属性(没有额外的代码)来做,但你可以用反射强制进行类型初始化。
例如:
foreach (Type type in assembly.GetTypes())
{
ConstructorInfo ci = type.TypeInitializer;
if (ci != null)
{
ci.Invoke(null);
}
}
请注意,此不会调用泛型类型的类型初始值设定项,因为您需要指定类型参数。您还应该注意,它将强制类型初始化程序运行,即使它已经运行,它在面对正常体验时会飞行。我建议如果你真的需要这样做(我试图改变你的设计,如果可能你不需要它)你应该创建自己的属性,并将代码更改为类似的东西:
foreach (Type type in assembly.GetTypes())
{
if (type.GetCustomAttributes(typeof(..., false)).Length == 0)
{
continue;
}
ConstructorInfo ci = type.TypeInitializer;
if (ci != null)
{
ci.Invoke(null, null);
}
}
你可以用LINQ做到这一点,诚然:
var initializers = from type in assembly.GetTypes()
let initializer = type.TypeInitializer
where initializer != null &&
type.GetCustomAttributes(typeof(..., false).Length > 0
select initializer;
foreach (ConstructorInfo initializer in initializers)
{
initializer.Invoke(null, null);
}
答案 1 :(得分:5)
只需在应用程序开头引用该类型的静态字段即可。没有办法通过改变类定义站点上的代码来实现这一目的。
答案 2 :(得分:1)
答案 3 :(得分:1)
CLR支持module initializers,这可能就是你要找的东西。相反,考虑到你的标签是学术性的,这个功能在C#语言中是不可用的,只有C ++ / CLI语言。
解决方法完全无痛,请明确调用静态方法(Initialize?)。
答案 4 :(得分:0)
好的,我发现这可以通过以下方式完成。在Main()中调用InvokeImplicitInitializers()将在已定义该方法的每个类中调用Initialize()。
using System;
using System.Reflection;
namespace Test
{
public class Class1
{
static Class1()
{
Console.WriteLine("Class1: static constructor");
}
public static void Initialize()
{
Console.WriteLine("Class1: initialize method");
}
}
public static class Class2
{
public static void Initialize()
{
Console.WriteLine("Class2: initialize method");
}
}
class MainClass
{
public static void InvokeImplicitInitializers(Assembly assembly)
{
foreach (Type type in assembly.GetTypes())
{
MethodInfo mi = type.GetMethod("Initialize");
if (mi != null)
{
mi.Invoke(null, null);
}
}
}
public static void Main (string[] args)
{
InvokeImplicitInitializers(Assembly.GetCallingAssembly());
}
}
}
你怎么看?它是模式还是模式?