使用new进行静态变量初始化会产生代码危险

时间:2014-03-05 11:31:26

标签: c# constructor static static-members static-constructor

我正在研究一些类似的代码:

class A
{
   static SomeClass a = new Someclass("asfae");  
}

Someclass包含必需的构造函数。 这个代码编译好没有任何警告。但是我在系统中遇到了代码危险:

  

“Someclass ctor已经从静态构造函数和/或   静态初始化“

这个代码危害了系统的一部分,只是为了通过警告系统中可能存在的缺陷或系统因此而陷入不良状态来使其更好。 我在网上的某处读到静态构造函数/初始化程序可以在c#中等待线程完成时陷入死锁。这与此有关吗?

我需要摆脱这个警告我该怎么做。 由于静态函数使用它,我不能使该成员为静态。 在这种情况下我该怎么做,需要帮助。

3 个答案:

答案 0 :(得分:1)

您可以将其隐藏在属性后面并在首次使用时初始化(非线程安全);

class A
{
    static SomeClass aField;

    static SomeClass aProperty
    {
        get
        {
           if (aField == null) { aField = new Someclass("asfae"); }
           return aField;
        }
    }
}

或使用Lazy(线程安全):

class A
{
    static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}

...或者这个非常详细的线程安全版本:)

class A
{
    static SomeClass aField;

    static object aFieldLock = new object();

    static SomeClass aProperty
    {
        get
        {
           lock (aFieldLock)
           {
               if (aField == null) { aField = new Someclass("asfae"); }
               return aField;
           }
        }
    }
}

答案 1 :(得分:0)

通过将其初始化为静态字段,它的行为与在静态构造函数中的行为相同,即它可能在第一次实例化类的实例时初始化,但可能更早发生。如果您想要更准确地控制字段初始化的时间,可以使用Lazy<T>,例如:

{
   static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));  
}

这样,您就知道SomeClass的初始化只会在第一次访问字段并调用其Value属性时发生。

答案 2 :(得分:0)

我认为要理解你的问题,你需要知道静态构造函数和类型初始值设定项之间的区别,Jon Skeet有一篇关于这个问题的精彩文章:

http://csharpindepth.com/Articles/General/Beforefieldinit.aspx

关键是以下结构不一样,并且行为有所不同:

class Test
{
    static object o = new object();
}

class Test
{
    static object o;

    static Test()
    {
        o = new object();
    }
} 

在任何情况下,您都可以尝试为您的类创建一个静态构造函数,以便能够对此初始化进行更多控制,并且警告可能会消失。

如果该成员仅由静态方法使用,并且仅由此方法使用,我建议您将其放在范围内,如果是静态方法而不是类成员。