VB.NETでも静的なローカル変数を使いたい

はじめに

この前、ふとVBのキーワード一覧を見ていたらStaticなる物を見つけました。

Static (Visual Basic)

どうも静的なローカル変数を宣言する時に使うもののようです。 正直VBオブジェクト指向言語を標榜しているならこんなものは要らないはずですが、なぜかあります。

まぁ、あるもんはあるんですからしゃーないですけど。

サンプルコード

Staticが指定された変数は以下の特徴があります。

とまぁ、だからこれってプライベートなフィールドで良くね?という感じです。

Module Module1

    Sub Main()
        Dim a = New Hoge()
        Console.WriteLine(a.Sum(50))
        Console.WriteLine(a.Sum(100))
    End Sub

End Module

Class Hoge
    Function Sum(value As Integer) As Integer
        Static Dim total As Integer = 100
        total += value
        Return total
    End Function
End Class
150
250

実際のところコンパイラによって内部でプライベートなフィールドに置き換えられるのでマジで何であるのかが分からない。

スレッドセーフ

このキーワードでググっていたら

Staticで宣言された変数はスレッドセーフ

なる書き込みを見た気がしました。幻覚かもしれませんが。

確認の為に逆アセンブル結果を見てみたら確かに初期化部分はスレッドセーフに出来ていました。 しかし、肝心のロジック部分はスレッドセーフにはなっておらず、複数のスレッドで実行したら値が結果がおかしくなりそうです。 正確には常に正しい保証はどこにもないです。 マルチスレッドに係るバグは再現性の無いものも多いですから、一度上手くいったからって2回目以降も上手くいくとは限りません。

それに二回目以降も初期化の為の同期のオーバーヘッドが生じるので、ループ内でぶん回すにはちょっと考えものです。 結論としましては、宗教上の理由がない限り使わないほうがよさそうです。

おわり