2017-06-03 35 views
1

我目前使用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」,「Fly,4,8 -7,5,7「},第二級將首先枚舉上層的第一個元素,並返回{」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

我覺得你有與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

+0

感謝您的反饋。首先,我會回覆你的附註。在我的默認屬性裏面,我處理基於1和基於0的定位之間的轉換。關於您的其他建議,我可能需要一些幫助,因爲我只在6個月內編寫了VB.NET。我們使用RocketD3,因此已經有了免費的類庫;這只是一個學習練習,我給自己擴展了我對VB的理解,可能比我咀嚼的東西還要多。無論如何,我如何降低到最低水平?我不明白你的意思。 –

+0

再次審查您的答案後,我現在理解得更好。謝謝你的建議。 –

+0

很有意思。查看適用於UO.NET的C#或VB.NET示例。也可以考慮向U2/MVDBMS特定論壇交叉發佈此類問題。而且(雖然這通常是徒勞的),可以考慮詢問你的VAR。 – TonyG

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()) 
+0

我不知道我將如何實現詞典到類所以我添加了我目前所嘗試的。 –

+0

查看發佈:https://stackoverflow.com/questions/20216583/custom-collection-of-t – jdweng