Как переопределить общую / конструкторскую функцию Visual Basic - PullRequest
0 голосов
/ 21 ноября 2018

В настоящее время я использую Visual Basic для проекта колледжа, который требует от нас создания простой системы баз данных.Для моей системы у меня есть базовый (абстрактный) класс, называемый Record, который наследуется различными типами записей, которые есть в моей базе данных, например Member, User, Role.

Ясохранил мои данные в csv-файлах и уже написал класс CSVHandler.Тем не менее, я хочу элегантный способ создания экземпляра класса, производного от Record, со строкой из CSVHandler.

. Здесь возникает проблема.Единственный способ, которым я могу думать об этом, это сделать Constrcutor или Shared Function в каждом классе, полученном из Record.Однако Visual Basic не позволяет вам Constructors или Shared 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 голосов
/ 21 ноября 2018

Следующий ответ аналогичен ответу @jmcilhinney в том, что он заставляет производный класс реализовать метод инициализации.Однако он использует общую разделяемую функцию и использует малоизвестный метод GetUninitializedObject , чтобы обойти использование общего ограничения 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")
0 голосов
/ 21 ноября 2018

Пусть ваш конструктор вызовет метод 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, и вы по-прежнему не можете применить его.Я думаю, что я оставлю это как ответ, потому что, хотя на самом деле это не дает решения вашей проблемы, оно демонстрирует, почему (насколько я могу судить) такого решения не существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...