是否应避免使用静态引用类型变量?

时间:2013-09-24 19:44:38

标签: vb.net static

在单线程环境中考虑以下功能性的两个代码片段。假设Foo中没有其他方法,我相信这些方法在功能上是相同的。

  Class Foo
    Private _Bar As Bar
    Public ReadOnly Property GetBar As Bar
      Get
        If IsNothing(_Bar) Then
          _Bar = New Bar
        End If
        Return _Bar
      End Get
    End Property
  End Class

并且

  Class Foo
    Public ReadOnly Property GetBar2 As Bar
      Get
        Static _Bar As New Bar
        Return _Bar
      End Get
    End Property
  End Class

今天我在第二种方法之后遇到了代码挑战,因为“每次都会调用New”。我已经知道that is false,但主要的反对意见是关于Static的使用。我发现了几个对静态变量的引用,表明它们可能很危险,但它们都在谈论Java。但是,我无法找到任何关于原因的好解释。

这两种方法有何不同?第二种方法危险吗?如果是这样,为什么?

3 个答案:

答案 0 :(得分:3)

VB.Net中的

Static与Java,C#,C或C ++中的static不同。 VB.Net与该构造的类比是Shared。有关Static关键字的文档如下:

  

http://msdn.microsoft.com/en-us/library/z2cty7t8.aspx

特别是,我想指出这个片段:

  

<强>行为

     

在Shared过程中声明静态变量时,只有一个静态变量副本可用于整个应用程序。您可以使用类名调用Shared过程,而不是指向类实例的变量。

     

在非共享的过程中声明静态变量时,该类的每个实例只能使用该变量的一个副本。您可以使用指向该类的特定实例的变量来调用非共享过程。

反对意见可能来自于相信Static总是表现得像第一段,即使在实例方法中,当我们在这里看到明确证明情况并非如此时。

相反,Static允许您声明一个变量,其 lifetime-scope 是类实例的变量,但其访问范围仅限于单个方法。这是缩小变量的潜在范围的一种方式,因此是一件好事。此外,声明为Static的变量由编译器重写,以通过Monitor类(至少对于Shared版本)进行保护,从而为它们提供线程安全性的测量。换句话说,声明为Static的变量更可能以完成与类似的类范围变量相关的任何所需锁定。

但在这种特殊情况下,我没有看到这一点。除了像这样的自动实现的属性之外,你真的没有获得任何东西:

Public ReadOnly Property GetBar2 As New Bar()

答案 1 :(得分:1)

这可能会混淆StaticShared的VB.net概念,因为有些语言使用关键字Static来表示VB使用Shared的内容:变量/对所有类实例共享或共用的字段/属性/方法。

但是Static并不意味着在VB中。相反,它意味着一个例程本地变量,它持续超出了例程的调用(即,它的生命周期是对象作用域而不是例程调用作用域)。

参考:http://msdn.microsoft.com/en-us/library/z2cty7t8.aspx

所以在VB中,Static表示“例程范围的可见性,对象范围的生命周期”。

Shared的意思是“类范围的可见性,类/程序范围的生命周期”。

答案 2 :(得分:1)

如果没有其他原因,除了C和C#的static关键字的含义与VB.NET Static关键字的含义完全不同之外,我会避免使用第二种方法。我一般不喜欢看起来像其他语言的功能但不是。如果有必要使用语言功能,尽管它与其他语言的功能非常相似,我将使用它,但VB.NET静态关键字在这里并没有真正增加太多。实际上,它要求编译器生成变量Private字段,给它一个不同于任何其他字段的任意名称,并替换方法中对变量的给定名称​​的所有引用引用了本发明的名称。

从概念上讲,使用这样的“本地化”字段可能被认为是可疑的,因为虽然人们可能期望只需要在一种方法中使用字段,但这可能结果不是真的。但是,我不会过多担心vb.net中的这个问题,因为如果需要,Static变量很容易变成普通的私有字段。如果在需要的时候出现了一个具有相同名称的字段,可以在移动之前轻松重命名Static变量。