如何在 c# 中使用静态字段初始值设定项和非默认类构造函数



我有以下代码,这让我很困惑。问题是,当静态字段 abc 将由 CLR 初始化时,它将是类 ABC 的实例化,这将进一步实例化类 XYZ。我的困惑是,在多线程环境中,在线程对类程序及其成员执行任何操作之前,CLR 已经初始化了字段 abc,这意味着任何尝试运行 DoSomething() 方法的线程都必须共享 abc 字段(这也是 ABC 的一个实例)。这是否意味着类 XYZ 将只实例化一次,因为 CLR 只初始化了一次 abc 字段,它是一个共享字段。

public class XYZ
{
    public XYZ(string nameOfClass)
    {
        Console.WriteLine("XYZ ctor ran");
    }
}
public class ABC
{
    private XYZ xyz = null;
    public ABC(string nameOfClass)
    {
        xyz = new XYZ(nameOfClass);
    }
    public void DoSomething()
    {
        Console.WriteLine("DoSomething Ran");
    }
}

public class SomeClass
{
   static  ABC abc = new ABC("Program");
   public  void Helper()
    {
        abc.DoSomething();
    }
}
public class Program
{
    static void Main()
    {
        SomeClass sc = new SomeClass();
        SomeClass sc2 = new SomeClass();
        for (int i = 0; i < 20; i++)
        {
            new Thread(sc.Helper).Start();
        }
        sc2.Helper();
    }
}

这是否意味着类 XYZ 将只实例化一次,因为 CLR 只初始化了一次 abc 字段,它是一个共享字段。

是的。 只有一个XYZ实例,因为只有一个ABC实例。

我要指出的是,您发布的代码都没有显示任何线程不安全的代码,因此不清楚您的担忧是什么。 您可能有多个线程同时执行DoSomething

静态字段在第一次访问类时初始化。请参阅 MSDN

类在其类构造函数(静态 C#中的构造函数,Visual Basic中的共享子新增功能)已完成 运行。防止在不是 初始化后,公共语言运行库会阻止来自其他语言的所有调用 类的静态成员的线程(视觉对象中的共享成员 基本),直到类构造函数完成运行。

最新更新