为自定义类

时间:2017-06-03 02:01:19

标签: vb.net visual-studio-2015 multivalue

我目前正在使用Visual Basic在Visual Studio 2015中工作,我有一个带有分隔字符串的类,可以在字符串中的位置提取/替换数据,类似于锯齿状数组,最多可达三级。我可以扩展课程以处理超过三个级别,但是现在,我会坚持使用这三个级别。对于熟悉的人来说,这就像PICK mvdbms数据结构。已经构建了在类中读取和写入数据的基类。为了节省空间和权宜之计,我已将编辑后的代码作为参考来帮助解决我的问题。如果需要更多数据,我可以提供全班。另外,如果在讨论这个问题时有一些问题或建议需要改进我的代码,我总是愿意倾听建设性的反馈。

班级:

Public Class MVString

#Region " Properties "
    Private Record As String
    Default WriteOnly Property MV(ByVal str As String) As MVString
        Set
            Record = str
        End Set
    End Property

    Default Public Property MV(ByVal AMPos As Integer) As MVString
       'Get and set value at top level
    End Property

    Default Public Property MV(ByVal AMPos As Integer, ByVal VMPos As Integer) As MVString
        'Get and set value at middle level
    End Property

    Default Public Property MV(ByVal AMPos As Integer, ByVal VMPos As Integer, ByVal SMPos As Integer) As MVString
        'Get and set value at deepest level
    End Property
#End Region

#Region " Constructors "
    Public Sub New()
        Record = ""
    End Sub

    Public Sub New(ByVal str As String)
        Record = str
    End Sub
#End Region

#Region " Methods "
    Public Sub Clear()
        Record = ""
    End Sub

    Public Overrides Function ToString() As String
        Return Record
    End Function
#End Region

#Region " Operators "
    Public Shared Widening Operator CType(v As String) As MVString
        Return New MVString(v)
    End Operator

    Public Shared Widening Operator CType(v As MVString) As String
        Return v.ToString
    End Operator
#End Region

End Class

我的问题是:如何为此类创建可枚举的支持并将其限制为三个级别,以便系统知道它所在的级别以及需要使用哪个分隔符?例如,如果我有以下变量:

Dim DelimitedString As String =" Foo,4,7,1-2,,6 | Bar,4,2,8-7,5,7 | Fly,4,,8-7,5, 7"

顶级的分隔符是" |",第二级是","而最深层次将是" - "。在这个例子中,顶层将是一个数组{" Foo,4,7,1-2,,6"," Bar,4,2,8-7,5,7&# 34;," Fly,4,,8-7,5,7和#34;},第二级将首先枚举上层的第一个元素,并返回{" Foo" ," 4"," 7"," 1-2",""," 6"}等...

关于从哪里开始的任何想法?

更新

我不确定如何将字典纳入课程,所以我已经用我之前提出的内容更新了我的帖子。

Public Function GetEnumerator() As IEnumerator(Of String) Implements IEnumerable(Of String).GetEnumerator
    Return New MVStringEnumerator(Record)
End Function

Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
    Return Me.GetEnumerator()
End Function

Private Class MVStringEnumerator
    Implements IEnumerator(Of String)

    Private _ThisArray() As String
    Private idx As Integer

    Public ReadOnly Property Current As String Implements IEnumerator(Of String).Current
        Get
            Return If(idx < _ThisArray.Count, _ThisArray(idx), DirectCast(Nothing, String))
        End Get
    End Property

    Private ReadOnly Property IEnumerator_Current As Object Implements IEnumerator.Current
        Get
            Return Me.Current
        End Get
    End Property

    Public Sub New(ByVal record As String)
        Select Case True
            Case record.Contains("|"c)
                _ThisArray = Split(record, "|"c)
            Case record.Contains(","c)
                _ThisArray = Split(record, ","c)
            Case record.Contains("-"c)
                _ThisArray = Split(record, "-"c)
        End Select
        idx = -1
    End Sub

    Public Sub Reset() Implements IEnumerator.Reset
        idx = -1
    End Sub

    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
        idx += 1
        If idx >= _ThisArray.Count Then Return False
        Return True
    End Function

End Class

2 个答案:

答案 0 :(得分:2)

我认为你对MVStringEnumerator有正确的想法,你最终枚举了一个字符串数组而不是MV分隔字符串。 (作为MVDBMS专家,我理解您的参考资料。)这可能相当简单。我将消除此任务的双重职责,解析分隔符和枚举。

首先将枚举对象缩小到所需动态数组的最低级别:

myValue = myMVString.MV(1,4)

其次,使其可枚举:

mySubValues = myValue.AsEnumerable()

最后,将mySubValues枚举为常见的字符串数组。因此枚举不知道原始动态数组的MV特性。 当然,以上所有内容都可以更优雅地完成,并封装到一个返回所需枚举的方法中,如:

myEnumerable = myMVString.AsEnumerable(1,4)

或者最终只是迭代new MyEnumerable(myMVSTRING(1,4))之类的内容。

请注意,如果您真的使用MVDBMS,每个平台都有自己的免费类库来执行此类操作:MVSP,UO.NET,QMClient等。所以您可能不需要编写此代码从头开始 - 虽然这是一个很好的练习。

旁注

如果要模拟MV动态数组,则代码使用基数索引0,其中MV使用1。

答案 1 :(得分:0)

我喜欢使用字典

        Dim input As String = "Foo,4,7,1-2,,6|Bar,4,2,8-7,5,7|Fly,4,,8-7,5,7"

        Dim dict As Dictionary(Of String, String()) = input.Split("|").Select(Function(x) x.Split(",")) _
           .GroupBy(Function(x) x(0), Function(y) y.Skip(1).ToArray()) _
           .ToDictionary(Function(x) x.Key, Function(y) y.FirstOrDefault())