1

Consider the following functionally two code snippets in a single-threaded environment. Assuming there are no other methods in Foo I believe these are functionally identical.

  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

And

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

Today I was challenged on code following the 2nd method because "the New will be called each time". I already know that is false, but the primary objection was with regards to the use of Static. I found several references to Static variables indicating that they may be dangerous, but they were all talking about Java. However, I was not able to find any good explanations as to why.

How are these two methods different? Is the 2nd method dangerous? If so, why?

Community
  • 1
  • 1
Daniel
  • 12,982
  • 3
  • 36
  • 60
  • While it is similar, I was wanting to differentiate between reference types instead of value types. Perhaps I'm mistaken in thinking they should be considered differently. – Daniel Sep 24 '13 at 19:58

3 Answers3

3

Static in VB.Net is not that same as static in Java, C#, C, or C++. VB.Net's analog to that construct is Shared. The documentation on the Static keyword is here:

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

In particular, I'd like to point out this snippet:

Behavior

When you declare a static variable in a Shared procedure, only one copy of the static variable is available for the whole application. You call a Shared procedure by using the class name, not a variable that points to an instance of the class.

When you declare a static variable in a procedure that isn't Shared, only one copy of the variable is available for each instance of the class. You call a non-shared procedure by using a variable that points to a specific instance of the class.

It's likely the objection comes from believing that Static always behaves like the first paragraph, even in instance methods, when we can see here that it's clearly documented that this is not the case.

Instead, Static allows you to declare a variable whose lifetime-scope is that of the class instance, but whose access-scope is limited to a single method. It's a way to narrow the potential scope of a variable, and therefore is a good thing. Additionally, variables declared as Static are rewritten by the compiler to be protected via the Monitor class (at least for the Shared version), giving them a measure of thread-safety. In other words, a variable declared as Static is more likely to have any needed locking done verses a similar class-scoped variable.

In this particular case, though, I fail to see the point. You don't really gain anything beyond an auto-implemented property like this:

Public ReadOnly Property GetBar2 As New Bar()
Community
  • 1
  • 1
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • That's a cool trick, however `Public ReadOnly Property GetBar2 As New Bar()` does not compile. [This reference](http://msdn.microsoft.com/en-us/library/dd293589.aspx) indicates that "properties that are WriteOnly or ReadOnly." require standard syntax. – Daniel Sep 24 '13 at 20:10
  • Hmm... I could swear I've written code like that before, but it seems you're right. In that case, what you have there is a read-only property without the need for class-scoped backing field. I'd call that a good thing. Just keep in mind that, for reference types, it's still possible to change properties of the object. – Joel Coehoorn Sep 24 '13 at 20:16
  • 1
    Hmm, I think you've Skeeted me... ;-) – RBarryYoung Sep 25 '13 at 17:32
1

This probably is confusing the VB.net concepts of Static and Shared because some languages use the keyword Static to mean what VB uses Shared for: a variable/field/property/method that is shared or common to all instances of a class.

But Static doesn't mean that in VB. Instead it means a routine-local variable that persists beyond the invocation of the routine (i.e., its lifetime is object-scoped rather than routine invocation-scoped).

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

So in VB, Static means "routine-scoped visibility, object-scoped lifetime".

Whereas Shared means "class-scoped visibilty, class/program-scoped lifetime".

RBarryYoung
  • 55,398
  • 14
  • 96
  • 137
1

I would avoid the second approach if for no other reason than the fact that C and C# have a static keyword whose meaning is totally different from that of the VB.NET Static keyword. I generally dislike language features which look like features of other languages but aren't. If it's necessary to use a language feature despite its unfortunate resemblance to the other language's feature, I'll use it, but the VB.NET static keyword doesn't really add much here. Effectively, it asks the compiler to make the variable Private field, give it an arbitrary name which differs from that of any other field, and replace all references to the variable's given name within the method with references to the invented name.

Conceptually, use of such "localized" fields may be regarded as dubious because while one may expect that a field will only need to be used within one method, that may turn out not to be true. I wouldn't worry too much about that issue in vb.net, however, because a Static variable may easily be turned into an ordinary private field if the need arises. If when that need does arise a field exists with the same name, one may easily rename the Static variable before moving it.

supercat
  • 77,689
  • 9
  • 166
  • 211