何时在类中初始化内联静态变量?

时间:2010-08-10 13:55:16

标签: .net vb.net class static

假设我们有一个类:

Public Class Question 

    Private Shared _field as Integer = CrazyIntegersRepository.GetOne()

    ' Some other useful things go here

End Class

GetOne方法引发异常......我们如何管理?将其重写为静态构造函数是一种很好的做法吗? 如果我们在内联_field声明中将它留在那里,GetOne方法何时会被执行?

3 个答案:

答案 0 :(得分:4)

注意:我假设VB的工作方式与C#相同。如果他们对此有所不同,我会感到惊讶。

如果你把它留在那里(并且没有静态构造函数),它将取决于你正在使用的.NET版本。它只能保证“在第一次引用静态字段之前的某个时刻”运行。您甚至可以创建实例,并且类型初始值设定项可能无法运行!如果你有一个静态构造函数(甚至是一个空构造函数),在第一次引用任何构造函数或任何静态成员之前,类型初始化程序将直接直接运行。 (基本上,几乎所有你用它做的事情都会初始化它。)

与.NET 3.5 as I blogged about相比,.NET 4中实际观察到的行为变得更加模糊。请注意,这只是谈论桌面框架;我不知道Silverlight或Compact Framework是做什么的。

如果该方法可以抛出一个异常,我首先想要在一个方法调用中更懒惰地执行它,可能会适当地缓存结果。这样,该方法可以让异常冒泡,调用者可以稍后再试。如果它是您正在考虑的潜在瞬态异常,这是合适的。如果它表明整个系统无法使用,那么让类型初始化程序失败就可以了。

答案 1 :(得分:0)

关于管理可能的例外的问题,请继续关注那个问题。任何可以创建异常的代码都应放入方法中。在这种情况下,构造函数将是最好的位置。所以可能是这样的:

Public Sub New()
    Try
        _field as Integer = CrazyIntegersRepository.GetOne()
    Catch ex As Exception
        'log it / deal with it as you will
    End Try
End Sub

答案 2 :(得分:0)

如果按照p.campbell的建议,你必须至少声明一个类的实例才能初始化_field变量。我假设,从变量声明中的Shared关键字开始,您希望可以从类的所有实例访问它,无论它们是否已经过专门初始化。

为了实现该功能,您必须按如下方式修改您的课程:

Public Class Question 

    Private Shared _field as Integer

    Shared Sub New()
        _field = CrazyIntergersRepository.GetOne()
    End Sub
    ' Some other useful things go here

End Class


使用此方法,_field变量将在第一次使用类时初始化,因为默认构造函数声明为 Shared 。您可以选择将方法包装在Try...Catch块中,以捕获可能发生的异常。