簡體   English   中英

強制構造靜態物體

[英]Force construction of static objects

正如我所知,類中的靜態對象是在第一次引用類時構造的。 但是我發現在程序啟動時初始化靜態有時很有用。 是否有一些方法(即通過使用注釋)來執行它?

你不能用屬性(沒有額外的代碼)來做,但你可以用反射強制類型初始化。

例如:

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);
}

只需在應用程序開頭引用該類型的靜態字段。 沒有辦法單獨通過改變類定義站點的代碼來實現這一點。

您可以使用RuntimeHelpers.RunClassConstructor運行任意類型的初始值設定項

CLR支持模塊初始化器 ,這可能就是您正在尋找的。 相反,考慮到你的標簽,這個功能在C#語言中是不可用的,只有C ++ / CLI語言。

解決方法完全無痛,請顯式調用靜態方法(Initialize?)。

好的,我發現這可以通過以下方式完成。 在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());
        }
    }
}

你怎么看? 它是模式還是模式?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM