强制构造静态物体

时间:2009-12-30 08:04:38

标签: c# .net

正如我所知,类中的静态对象是在第一次引用类时构造的。但是我发现在程序启动时初始化静态有时很有用。是否有一些方法(即使用注释)强制执行它?

5 个答案:

答案 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)

您可以使用RuntimeHelpers.RunClassConstructor

运行任意类型的初始值设定项

答案 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());
        }
    }
}
你怎么看?它是模式还是模式?