2017-06-03 3 views
1

Ich arbeite derzeit in Visual Studio 2015 mit Visual Basic und ich habe eine Klasse, die eine Zeichenfolge mit Trennzeichen und kann Daten an Positionen innerhalb der Zeichenfolge, ähnlich einem gezackten Array, nach oben/extrahieren/ersetzen auf drei Ebenen tief. Ich kann die Klasse erweitern, um tiefer als drei Ebenen zu handeln, aber für den Moment bleibe ich bei den dreien. Dies ist genau wie eine PICK mvdbms Datenstruktur für diejenigen, die vertraut sind. Die Basisklasse zum Lesen und Schreiben der Daten innerhalb der Klasse wurde bereits erstellt. Aus Platz- und Zweckmäßigkeitsgründen habe ich redigierten Code als Referenz zur Unterstützung meiner Frage hinzugefügt. Wenn mehr Daten benötigt werden, kann ich die gesamte Klasse bereitstellen. Auch wenn es während der Diskussion dieser Frage Bedenken oder Vorschläge gibt, meinen Code zu verbessern, bin ich immer bereit, konstruktives Feedback zu hören.Fügen Sie geschachtelte aufzählbare Unterstützung benutzerdefinierte Klasse hinzu

Die Klasse:

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 

Meine Frage ist: Wie gehe ich über zählbare Unterstützung für diese Klasse zu schaffen und es auf den drei Ebenen begrenzen, so weiß das System, das es auf und die Begrenzer waage muss verwendet werden? Zum Beispiel, wenn ich folgende Variable habe:

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

Das Trennzeichen für die oberste Ebene wäre das" | ", die zweite Ebene wäre", "und die tiefste Ebene wäre" - ". In diesem Fall wäre die oberste Ebene ein Array {"Foo, 4,7,1-2,, 6", "Bar, 4,2,8-7,5,7", "Fly, 4,, 8 -7,5,7 "}, die zweite Ebene würde zuerst durch das erste Element in der oberen Ebene aufzählen und {Foo", "4", "7", "1-2", "", "6 zurückgeben "}, etc ...

Irgendwelche Ideen, wo ich anfangen soll?

Update:

Ich bin nicht sicher, wie das Wörterbuch in die Klasse zu integrieren, so habe ich meine Post aktualisiert mit dem, was ich mit vor gekommen war.

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 

Antwort

2

Ich glaube, Sie haben die richtige Idee mit dem MVStringEnumerator, wo Sie schließlich ein Array von Strings statt einer MV getrennte Zeichenfolge aufzählt. (Als MVDBMS-Experte verstehe ich Ihre Referenzen.) Das könnte ziemlich einfach sein. Ich würde die doppelte Aufgabe dieser Aufgabe eliminieren, Trennzeichen und Aufzählung analysieren.

Zuerst Whittle die aufgezählten Objekt bis auf die unterste Ebene des dynamischen Arrays gewünscht:

myValue = myMVString.MV(1,4)

Zweitens, machen, dass enumerable:

mySubValues = myValue.AsEnumerable()

Last, aufzuzählen mySubValues ​​als gemeinsames Array von Strings. Die Enumeration ist sich der MV-Natur des ursprünglichen dynamischen Arrays nicht bewusst. Natürlich sind alle der oben eleganter gemacht und können in einem einzigen Verfahren eingekapselt, dass die zählbare gewünschten zurückgibt, wie:

myEnumerable = myMVString.AsEnumerable(1,4)

Oder letztlich nur über wie new MyEnumerable(myMVSTRING(1,4)) etwas laufen.

Beachten Sie, dass, wenn Sie tatsächlich mit einem MVDBMS arbeiten, jede Plattform ihre eigenen freien Klassenbibliotheken hat, um diese Art von Dingen zu tun: MVSP, UO.NET, QMClient, usw. Sie müssen also möglicherweise nicht schreiben Scratch überhaupt - obwohl es eine gute Übung ist.

Exkurs

Wenn Sie MV dynamische Arrays emulieren, verwendet Ihr Code einen Basisindex von 0, wobei MV verwendet 1.

+0

Vielen Dank für Ihr Feedback. Zuerst antworte ich auf deine Randnotiz. Innerhalb meiner Standardeigenschaften handle ich die Konvertierung zwischen 1-basierter und 0-basierter Positionierung. Was Ihre anderen Vorschläge angeht, brauche ich vielleicht Hilfe, da ich VB.NET erst seit 6 Monaten programmiert habe. Wir verwenden RocketD3, also gibt es bereits die freie Klassenbibliothek; Das war nur eine Lernübung, die ich mir gegeben habe, um mein Verständnis von VB zu erweitern, und wahrscheinlich etwas mehr, als ich kauen kann. Wie auch immer, wie schneide ich auf die unterste Ebene? Ich verstehe nicht, was du meinst. –

+0

Nachdem ich deine Antwort noch einmal durchgesehen habe, verstehe ich es jetzt besser. Vielen Dank für Ihre Vorschläge. –

+0

Froh, dass es Sinn ergab. Suchen Sie nach C# - oder VB.NET-Beispielen für UO.NET. Überlegen Sie auch, wie Sie solche Anfragen an U2/MVDBMS-spezifische Foren weiterleiten. Und (während dies normalerweise sinnlos ist), fragen Sie Ihren VAR nach Informationen. – TonyG

0

Ich mag mit einem Wörterbuch

 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

Ich bin nicht sicher, wie ich das Wörterbuch in meiner Klasse implementieren würde also habe ich hinzugefügt, was ich gerade probiert habe. –

+0

Siehe Beitrag: https://stackoverflow.com/questions/20216583/custom-collection-of-t – jdweng

Verwandte Themen