为单例对象/表单创建通用定义

时间:2016-01-17 16:32:30

标签: vb.net generics inheritance singleton

我想在vb.net中使用单例行为创建通用解决方案来实例化我的表单。但它无论如何都无法正常工作并且总是保护我编译:

Public Class SingletonGenerator(Of TForm)

    Private _inst As Object

    Public ReadOnly Property Instance As SingletonInstance(Of TForm)
        Get
            If _inst Is Nothing Then
                _inst = New TForm()
            End If
            Return _inst
        End Get
    End Property

End Class

但是这个错误限制我继续:

  

错误9'新'不能用于没有' New'的类型参数。约束

我不确定我是否用New Form()替换我的代码它按预期工作(因为它创建了父form()类的对象,并且可能会在子类中丢失一些初始化。)< / p>

有人可以解释为什么会发生这种情况,或者如何以OOP方式获得对象的单例实例,而不需要复制/粘贴在每个新定义的类中使用单例的常用代码行?

3 个答案:

答案 0 :(得分:2)

你必须说服编译器TForm类型实际上有一个无参数构造函数,以便New TForm()永远不会失败。这需要a constraint

不是唯一需要做的事情,Form对象在关闭时变得无法使用。你必须创建另一个重新显示它。如果不这样做,会在运行时导致ObjectDisposedException。换句话说,您应该对Disposed事件感兴趣。这需要进一步的约束,TForm类型参数总是需要从Form派生。需要说服编译器可以使用该事件。添加它:

Public Class SingletonGenerator(Of TForm As {Form, New})

    Private _inst As TForm

    Public ReadOnly Property Instance As TForm
        Get
            If _inst Is Nothing Then
                _inst = New TForm()
                AddHandler _inst.Disposed, Sub() _inst = Nothing
            End If
            Return _inst
        End Get
    End Property

End Class

对此有点小心,你正在把自己画成一个角落。您只能使用此代码来创建构造函数不带参数的表单对象。在实践中,您可能会发现他们经常需要一个。

答案 1 :(得分:1)

检查此代码:

Module Startup

    Public Sub Main()
        Dim f As Form = FormsManager.Instance.GetForm(Of Form1)()

        f.ShowDialog()

        Dim f1 As Form = FormsManager.Instance.GetForm(Of Form1)()

        f1.ShowDialog()
    End Sub

End Module

Public Class FormsManager
    Private Shared _formsManager As FormsManager
    Private _forms As List(Of Form)

    Public Shared ReadOnly Property Instance As FormsManager
        Get
            If (_formsManager Is Nothing) Then
                _formsManager = New FormsManager
            End If

            Return _formsManager
        End Get
    End Property


    Private Sub New()
        If _forms Is Nothing Then _forms = New List(Of Form)
    End Sub

    Public Function GetForm(Of T As {Form, New})() As Form
        Dim f As Form = _forms.Where(Function(o) o.GetType = GetType(T)).SingleOrDefault

        If f Is Nothing Then
            f = New T
            _forms.Add(f)
        End If

        Return f
    End Function

End Class

答案 2 :(得分:0)

这是我最终制作的(通用的单一形式生成器):

@Override
    protected void onPostExecute(String[] result) {
        super.onPostExecute(result);
        HashMap<String, List<String>> MoviesDetails = new HashMap<String, List<String>>();
        int count = result.length;
        for(int i=0; i<count;i++){
            List<String> result[i] = new ArrayList<String>();
         }

    }

并以这种方式称呼它:

Imports System.Windows.Forms
Imports System.Runtime.CompilerServices

<HideModuleName()> _
Public Module SingletoneForms

    <Extension> _
    Public Function GetInstance(Of TForm As {Form, New})(ByRef obj As TForm) As TForm
        Return SingletonForm(Of TForm).Instance
    End Function

    Public Class SingletonForm(Of TForm As {Form, New})

        Private Shared WithEvents _inst As TForm

        Public Shared Property Instance As TForm
            Get
                If _inst Is Nothing Then
                    SetInstance(New TForm())
                End If
                Return _inst
            End Get
            Set(value As TForm)
                SetInstance(value)
            End Set
        End Property

        Private Shared Sub SetInstance(ByVal newInst As TForm)
            If _inst IsNot Nothing Then
                RemoveHandler _inst.FormClosing, AddressOf FormClosing
            End If
            _inst = newInst
            AddHandler _inst.FormClosing, AddressOf FormClosing
        End Sub

        Private Shared Sub FormClosing(sender As Object, e As FormClosingEventArgs)
            If e.CloseReason = CloseReason.UserClosing Then
                e.Cancel = True
                _inst.Hide()
            Else
                _inst = Nothing
            End If
        End Sub

    End Class

End Module