如何必须重写共享/构造函数Visual Basic

时间:2018-11-21 02:34:42

标签: database vb.net inheritance constructor shared

我目前正在将Visual Basic用于一个大学项目,这需要我们制作一个简单的数据库系统。对于我的系统,我有一个名为Record的基(抽象)类,它由数据库中不同类型的记录继承,例如MemberUserRole

我将数据保存在csv文件中,并且已经编写了CSVHandler类。但是,我想要一种优雅的方法来构造Record派生的类的实例,并使用CSVHandler的字符串。

这是发生问题的地方。我能想到的唯一方法是在从Constrcutor派生的每个类中制作一个Shared FunctionRecord。但是,Visual Basic不允许将ConstructorsShared Functions也设为MustOverride

这是我希望编写的代码:

' Base Class
Public MustInherit Class Record
    Public MustOverride Shared Function fromString(ByVal str as String) As Record
End Class

' Example Of Class Derived From Record
Public Class User
    Inherits Record 

    Private _id As String
    Private _name As String

    Public Sub New(ByVal id As String, ByVal name As String)
        _id = id
        _name = name
    End Sub

    Public Overrides Shared Function fromString(ByVal str as String) As Record
        Dim strs() As String = str.Split(",")
        Return New User(strs(0), strs(1))
    End Function
End Class

' Example Of Creating Instacnce Of User
Dim user1 = User.fromString("1671,Kappeh")

有没有办法达到这种效果? 在此先感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

让构造函数调用进行初始化的Protected MustOverride方法。

Public MustInherit Class Record

    'This is required because each derived constructor must be able to implicitly invoke a parameterless
    'base constructor if it doesn't explicitly invoke a base constructor with parameters.
    Protected Sub New()
    End Sub

    Public Sub New(csv As String)
        Init(csv)
    End Sub

    Protected MustOverride Sub Init(csv As String)

End Class

Public Class User
    Inherits Record

    Private Property Id As String
    Private Property Name As String

    'This is still required because you can use a base constructor directly to create a derived instance.
    Public Sub New(csv As String)
        MyBase.New(csv)
    End Sub

    Public Sub New(id As String, name As String)
        Id = id
        Name = name
    End Sub

    Protected Overrides Sub Init(csv As String)
        'Add your type-specific implementation here.
    End Sub

End Class

这个“解决方案”实际上并没有达到我的预期,因为,尽管它迫使您重写派生类中的Init,但是您仍然必须提供派生构造函数,该构造函数调用调用Init,您仍然无法执行。我想我会留个答案,因为虽然它实际上并不能为您的问题提供解决方案,但它进一步说明了(据我所知)为什么没有这样的解决方案。

答案 1 :(得分:1)

以下与@jmcilhinney的回答类似,因为它强制派生类实现初始化方法。但是,它利用了通用的共享函数,并使用鲜为人知的GetUninitializedObject method来绕过通用的New约束,这是可访问的无参数构造函数的要求。

Public MustInherit Class Record
    Public Shared Function fromString(Of T As {Record})(ByVal str As String) As T
        ' create an unintialized instance of T 
        Dim ret As T = DirectCast(System.Runtime.Serialization.FormatterServices.GetUninitializedObject(GetType(T)), T)
        ret.Initialize(str)
        Return ret
    End Function

    Protected MustOverride Sub Initialize(source As String)
End Class

User类将是这样的:

Public Class User : Inherits Record
    Private _id As String
    Private _name As String

    Public Sub New(ByVal id As String, ByVal name As String)
        _id = id
        _name = name
    End Sub

    Protected Overrides Sub Initialize(source As String)
        Dim strs() As String = source.Split(","c)
        _id = strs(0)
        _name = strs(1)
    End Sub
End Class

用法示例:

Dim userRecord As User = Record.fromString(Of User)("1,2")