私は通常c#プログラマーですが、シングルトンクラスのセットアップに使用する場合、この1つのプロジェクトでVB)で作業しています。JonSkeetモデルに従います。
public sealed class Singleton
{
static Singleton instance = null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
//Added to illustrate the point
public static void a()
{
}
public void b()
{
}
}
または、c#でステートメントを記述した場合のバリエーションの1つ
Singleton.Instance
静的ではなく、bではなくaではないすべてのメンバーの手順は何ですか。
今私がVBで同じことをするとき
Private Shared _instance As StackTracker
Private Shared ReadOnly _lock As Object = New Object()
Private Sub New()
_WorkingStack = New Stack(Of MethodObject)
_HistoryStack = New Queue(Of MethodObject)
End Sub
Public Shared ReadOnly Property Instance() As StackTracker
Get
SyncLock _lock
If (_instance Is Nothing) Then
_instance = New StackTracker()
End If
End SyncLock
Return _instance
End Get
End Property
StackTracker.Instance.Instance
そしてそれは進み続けます、それは世界の終わりではありませんが、それは悪く見えます。
質問VBに2番目のインスタンスを非表示にして、ユーザーがインスタンスを再帰的に呼び出せないようにする方法はありますか?
完全なコードは次のとおりです。
Public NotInheritable Class MySingleton
Private Shared ReadOnly _instance As New Lazy(Of MySingleton)(Function() New
MySingleton(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication)
Private Sub New()
End Sub
Public Shared ReadOnly Property Instance() As MySingleton
Get
Return _instance.Value
End Get
End Property
End Class
次に、このクラスを使用するには、次を使用してインスタンスを取得します。
Dim theSingleton As MySingleton = MySingleton.Instance
これは実際にはジョンが出した提案ではありません。 この問題に関する記事で参照されている3番目のバージョン を実装しましたが、メモリバリアがないため、EMCA仕様に従って機能しないと彼は指摘しています。
むしろ、ネストされたクラスを使用し、ネストされたクラスの静的フィールドの宣言でインスタンスの割り当てを実行する5番目のバージョンを使用する必要があります。
.NET 4.0で作業している場合は、これを行う必要はありません。タイプ Lazy<T>
の静的読み取り専用フィールドを作成し、 LazyThreadSafetyMode.ExecutionAndPublication
をコンストラクターに渡すことができます(Func<T>
とともに、方法を示します)インスタンスを作成するには)値が1回だけ作成されることを保証します。
次に、 Lazy<T>.Value property
を呼び出すだけのプロパティを公開して、遅延読み込みされたシングルトン値を返します。
元の質問は、シングルトンパターンを実装する方法についてではなく、C#では、インスタンスを介して静的メンバーにアクセスしようとするとコンパイラエラーになるという事実に言及していました。現在のVBでは警告です。
解決策:プロジェクトコンパイラの設定を「すべての警告をエラーとして扱う」に変更できますが、警告42025だけをエラーとして明示的に扱う方法がわかりません。
そうは言っても、VBにシングルトンを実装するもっと簡単な方法もあります。
public class Singleton
private sub new()
end sub
public shared readonly property Instance as Singleton
get
static INST as Singleton = new Singleton
return INST
end get
end property
end class
これは、C#にはない機能である静的変数のVBスレッドセーフな単一初期化に依存しています。「静的」という単語で始まるコード行は、インスタンスプロパティであっても1回だけ評価されます。多くのスレッドから何度もアクセスされます。
何かが足りないかもしれませんが、クラスで他に何が起こっているかに応じて、これにいくつかのバリエーションを加えます。
Class MySingleton
'The instance initializes once and persists (provided it's not intentionally destroyed)
Private Shared oInstance As MySingleton = New MySingleton
'A property initialized via the Create method
Public Shared Property SomeProperty() As Object = Nothing
'Constructor cannot be called directly so prevents external instantiation
Private Sub New()
'Nothing to do
End Sub
'The property returns the single instance
Public Shared ReadOnly Property Instance As MySingleton
Get
Return oInstance
End Get
End Property
'The method returns the single instance while also initializing SomeProperty
Public Shared Function Create(
ByVal SomeParam As Object) As MySingleton
_SomeProperty = SomeParam
Return oInstance
End Function
End Class
明らかに、通常はどちらかInstance
プロパティまたはCreate
メソッドのみを提供し、両方は提供しません(ただし、必要に応じて提供することもできます)。何らかの理由で)。
最も単純な形式では、次のとおりです。
Class MySingleton
Private Shared oInstance As MySingleton = New MySingleton
Private Sub New()
End Sub
Public Shared ReadOnly Property Instance As MySingleton
Get
Return oInstance
End Get
End Property
End Class