2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

継承可能なSingleton基底クラス(VB.Net)

Last updated at Posted at 2016-02-09

改訂版書きました。
[改訂版]継承可能なSingleton基底クラス(VB.Net)


Singletonなクラスをある程度の個数作らなければいけなくなり、スニペットはあるもののなんとか継承を使用して解決できないか調査した。

参考にしたサイト

Singletonのサブクラス化
デザインパターン第14回「Singletonパターン」その2

基底クラス

AbstractSingletonClass.vb
''' <summary>
''' シングルトン基底クラス
''' </summary>
''' <remarks></remarks>
Public MustInherit Class AbstractSingletonClass

    ''' <summary>
    ''' シングルトンインスタンスリスト
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared _SingletonInstanceDictionary As New Dictionary(Of Type, AbstractSingletonClass)

    ''' <summary>
    ''' インスタンス生成排他ロックオブジェクト
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared ReadOnly _SyncLockCreateInstance As New Object

    ''' <summary>
    ''' コンストラクタ(Protected)
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub New()

        '唯一のインスタンスを保証する
        If _SingletonInstanceDictionary.ContainsKey(Me.GetType()) Then
            Throw New InvalidOperationException("インスタンスは既に生成されています。")
        End If

        '追加する
        _SingletonInstanceDictionary.Add(Me.GetType(), Me)

    End Sub

    ''' <summary>
    ''' インスタンス取得
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetInstance(Of T As AbstractSingletonClass)() As T

        SyncLock _SyncLockCreateInstance

            'インスタンス生成済みかチェックする
            If _SingletonInstanceDictionary.ContainsKey(GetType(T)) = False Then
                '無ければ生成する
                _SingletonInstanceDictionary(GetType(T)) = CType(System.Activator.CreateInstance(GetType(T), True), T)
            End If

            '返す
            Return CType(_SingletonInstanceDictionary(GetType(T)), T)

        End SyncLock

    End Function

End Class

派生クラス

SingletonA.vb
''' <summary>
''' 派生クラスA
''' </summary>
''' <remarks></remarks>
Public Class SingletonA
    Inherits AbstractSingletonClass

    ''' <summary>
    ''' コンストラクタ(Protected)
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub New()

    End Sub

End Class

使い方

Dim S = SingletonA.GetInstance(of SingletonA)()

今回勉強になったポイント

1.インスタンスを生成するActivator.CreateInstanceメソッドは、Publicなコンストラクタのみを実行するものだと思っていたが、第2引数次第でProtected、Privateでも生成してくれることを知った。

2.Sharedなメンバは「基底クラス.Sharedメンバ」とアクセスしなければいけないと思い込んでいたため、派生クラス内に基底クラス名が出現するが嫌で敬遠していた。だが「派生クラス.Sharedメンバ」でもOKなことを知った。

残る問題

こんな感じで使う時に型推論が効けば最高。

Dim S = SingletonA.GetInstance()

解決方法をご存知の方、コメントください。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?