2008.09.22 Monday
Shared のメンバ変数を公開しないこと
先日、こんなソースを見かけまして。
思わず寒気を感じた訳です。Shared変数は「そのような変数を Shared で宣言した場合、すべてのインスタンスがストレージ内の同じ場所にアクセスするため、あるインスタンスが変数の値を変更すると、すべてのインスタンスが変更後の値にアクセスするようになります。」[出典:MSDN ライブラリ- Shared(Visual Basic)] なので、昔のグローバル変数なみに訳の判らないことになる恐れがあるのです。
例えばこんなコード(及び改善例)
objHoge1.mstrHoge = "Instance"
は、ビット列の彼方に消え去っていきました。
そんな訳で、Sharedのメンバ変数には十分に気をつけましょうというお話でした。
で、問題のそのクラス、全てのメソッドがSharedで宣言されていたのですが、全てのメソッドが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なら、何故メンバ変数を公開する必要があるの??等など、疑問の尽きないコードでありました。






















