Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of static local variables in lazy loading property in VB.NET

I just recently learned about the uses of static local variables in VB.NET and wondered about it's potential use in lazy loading properties.

Consider the following example code.

Public Class Foo
  Implements IFoo
End Class

Public Interface IFoo
End Interface

Public Class Bar

  Private _fooImplementation As IFoo
  Public ReadOnly Property FooImplementation As IFoo
    Get
      If _fooImplementation Is Nothing Then _fooImplementation = New Foo
      Return _fooImplementation
    End Get
  End Property
End Class

This would be a usual, simplified lazy-loading property. You may even want to use the generic Lazy Class to get (as far as i know) the same behaviour.

Now, let's look at the property while using a static variable.

Public Class Bar

  Public ReadOnly Property FooImplementation As IFoo
    Get
      Static _fooImplementation as IFoo = New Foo
      Return _fooImplementation
    End Get
  End Property
End Class

As far as i can see, this has a few advantages over the usual implementation, primary your inability to access the variable outside of the property, as well as not having to use an additional variable.

My question to you is: Which of those is the "right" way to do it? I know that static variables have additional overhead, but is it bad enough to create, in my personal opinion, unclearer code that can be misused easier? How much performance do you lose compared to the "traditional" method? How does it matter for small classes compared to huge factories?

Thanks in advance.

like image 327
Lambda Avatar asked Oct 10 '22 23:10

Lambda


2 Answers

The Static keyword has rather a lot of overhead, the compiler generates a big chunk of IL to implement it. What it does do that your 1st snippet doesn't do is ensure that threading doesn't cause problems. If that is not a concern then your 1st snippet is a lot cheaper. Not just because it has a lot less IL but also because it will be inlined. A getter with Static will never be inlined since it contains Try/Finally code.

If you are targeting .NET 4 then you definitely should take a look at the Lazy(Of T) class.

like image 144
Hans Passant Avatar answered Oct 14 '22 05:10

Hans Passant


That question was interesting enough for me to find the answer...how exactly does VB.NET implement static. Here's a C# equivilent:

public class Bar
  {
    [SpecialName]
    private IFoo \u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation;
    [SpecialName]
    private StaticLocalInitFlag \u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init;

    public IFoo FooImplementation
    {
      get
      {
        Monitor.Enter((object) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init);
        try
        {
          if ((int) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State == 0)
          {
            this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State = (short) 2;
            this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation = (IFoo) new Foo();
          }
          else if ((int) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State == 2)
            throw new IncompleteInitialization();
        }
        finally
        {
          this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State = (short) 1;
          Monitor.Exit((object) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init);
        }
        return this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation;
      }
    }

    [DebuggerNonUserCode]
    public Bar()
    {
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init = new StaticLocalInitFlag();
    }
  }
like image 41
tcarvin Avatar answered Oct 14 '22 05:10

tcarvin