2014-03-05 38 views
5

我的一些代码的工作是这样的:静态变量初始化给出了一个代码危害

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

SomeClass的包含所需的构造。 此编译的代码没有任何警告。但是,我在系统中获取代码的危害:

系统

此代码的危险部分“的SomeClass的构造函数已经从静态构造函数和/或 静态初始化器被称为”只是使它变得更好警告系统中可能存在的缺陷,或者系统因此可能进入不良状态。 我在网上的某处读到,如果静态构造函数/初始化程序等待一个线程完成,它可能会在c#中陷入死锁。这与这有什么关系?

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

+0

那个静态字段的目的是什么? – Alex

回答

1

您可以将它隐藏在一个属性后面并在第一次使用时进行初始化(不是线程安全的);

class A 
{ 
    static SomeClass aField; 

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

或使用懒惰(线程安全的):

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; 
      } 
     } 
    } 
} 
+0

使用.net3.5懒惰不受支持,不想做非线程安全的解决方案。 – grv

0

通过初始化它作为一个静态字段,它的行为与静态构造函数中的行为相同,也就是说,它可能会在您的类的实例首次实例化时初始化,但可能会在较早时发生。如果你想在什么时候该领域被初始化更多的控制,你可以使用Lazy<T>,如:

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

这样,你就知道SomeClass的的初始化只会发生在第一时间现场访问和Value财产叫。

0

我想了解你的问题,你需要知道的静态构造和类型初始化的区别,有来自乔恩斯基特有关此问题的一个伟大的文章:

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

的一点是,下列建设是不一样的,并且有在行为差异:

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

class Test 
{ 
    static object o; 

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

在任何情况下,你可以尝试创建一个静态构造函数的类能够有更多个控制是初始化,也许警告将消失。

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

+0

该成员被其他方法使用,其中一些方法也不是静态的。 – grv

+0

@grv在这种情况下,您只能使用Lazy类(我经常使用它)或静态构造函数,它更快,也相当安全,并且线程安全。 – Rafa

+0

我正在使用.net 3.5所以使用懒惰不是一个选项,因为它不受支持,我试过静态构造函数,我仍然收到警告。任何其他想法? – grv