Shared のメンバ変数を公開しないこと

先日、こんなソースを見かけまして。

[VB.NET]
Public Class Hoge
 Public Shared fugafuga as String
 ’…以下略

思わず寒気を感じた訳です。Shared変数は「そのような変数を Shared で宣言した場合、すべてのインスタンスがストレージ内の同じ場所にアクセスするため、あるインスタンスが変数の値を変更すると、すべてのインスタンスが変更後の値にアクセスするようになります。」[出典:MSDN ライブラリ- Shared(Visual Basic)] なので、昔のグローバル変数なみに訳の判らないことになる恐れがあるのです。
例えばこんなコード(及び改善例)

[VB.NET]
Module Module1
  Sub Main()
    ‘—ダメな方のHogeの例
    
    Dim objHoge1 As New HorrorHoge
    objHoge1.mstrHoge = “Instance”‘—←コンパイラが警告を出します
    HorrorHoge.mstrHoge = “DirectHoge”
    Console.WriteLine(“Via Instance”)
    objHoge1.PrintHoge()‘—←コンパイラが警告を出します
    HorrorHoge.mstrHoge = “DirectHoge”
    Console.WriteLine(“DirectHoge”)
    HorrorHoge.PrintHoge()
    Console.WriteLine(“Hit any key…”)
    Console.ReadKey()
    ‘—マシなほうのHoge
    Dim objBetterHoge1 As New BetterHoge
    objBetterHoge1.Hoge = “hoge”
    Dim objBetterHoge2 As New BetterHoge
    objBetterHoge2.Hoge = “fuga”
    Console.WriteLine(“Better Hoge1″)
    objBetterHoge1.PrintHoge()
    Console.WriteLine(“Better Hog2″)
    objBetterHoge2.PrintHoge()
    Console.WriteLine(“Hit any key…”)
    Console.ReadKey()
  End Sub
End Module
‘ダメな方のHoge
Public Class HorrorHoge
  ‘Sharedなメンバ変数をPublicで公開します
  Public Shared mstrHoge As String
  Public Shared Sub PrintHoge()
    Console.WriteLine(“mstrHoge=” & mstrHoge)
  End Sub
End Class
‘マシな方のHoge
Public Class BetterHoge
  ‘とりあえずPropertyにしておきます
  Private mstrHoge As String
  Public Property Hoge() As String
    Set(ByVal value As String)
      mstrHoge = value
    End Set
    Get
      Return mstrHoge
    End Get
  End Property
  Public Sub PrintHoge()
    Console.WriteLine(mstrHoge)
  End Sub
End Class

で、実行結果は…

Via Instance
mstrHoge=DirectHoge
DirectHoge
mstrHoge=DirectHoge
Hit any key…
Better Hoge1
hoge
Better Hog2
fuga
Hit any key…

…ダメな方の
objHoge1.mstrHoge = “Instance”
は、ビット列の彼方に消え去っていきました。
そんな訳で、Sharedのメンバ変数には十分に気をつけましょうというお話でした。
で、問題のそのクラス、全てのメソッドがSharedで宣言されていたのですが、全てのメソッドがSharedなら、何故メンバ変数を公開する必要があるの??等など、疑問の尽きないコードでありました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam Protection by WP-SpamFree