In VB.Net sind die System.Arrays stets null-basiert. Falls man den Array-Index nur als eine Zugriffshilfe auf die einzelnen Array-Elemente^betrachtet, ist das keine besondere Einschränkung. Unter bestimmten Umständen kann es aber nützlich sein, wenn dem Array-Index auch eine inhaltliche Bedeutung zuzuordnen ist. Wertet man z.B. jahresbezogene Zeitreihen aus, die von 'ErstesJahr' (z.B. 1970) bis 'LetztesJahr' (z.B. 2008) erhoben worden sind, ist es zweckmäßig, die Daten in einem Array aufzubewahren, dessen Dimension von 1970 bis 2008 läuft. Der Array-Index besitzt in diesem Fall zugleich die Bedeutung: Jahreszahl. Die generische Klasse cArrayXToY erlaubt die Erstellung von ein- und mehrdimensionalen Arrays, deren Dimensions-Untergrenze(n) nicht 0 sein müssen, sondern beliebig wählbar sind. Für die Obergrenze jeder Dimension gilt, dass sie >= Untergrenze sein muß. Die Erstellung von Instanzen der Klasse erfolgt durch den Konstruktor (New), der zugleich den Datentyp des Array, die Zahl der Dimensionen und die Unter- und Obergrenzen jeder Dimension festlegt. (Vgl. Kommentarzeilen und Anwendungsbeispiel). Zusätzlich werden Hilfswerte für den effizienten Zugriff erstellt. Die Grenzen einer Array-Dimension können durch die Funktionen lbd/ubd abgefragt werden (1. Dimension = 0!). Die Klasse löst sowohl bei der Array-Deklaration (Konstruktor) als auch beim Array-Zugriff Ausnahmen aus, falls Dimensionen oder Indizes nicht plausibel sind. Auf die Implementierung der Methoden für Redim(Preserve), Clone und CopyTo ist der Einfachheit halber verzichtet worden. Die Anwendung solcher Funktionen auf nicht-nullbasierte Arrays ist ohnehin meist weniger empfehlenswert. Übersichtlicher ist es, das Zielarray (ggf. mit den Grenzen) explizit zu erstellen und die gewünschten Elemente in Schleifen sukzessive aus dem Quellarray zu übertragen. Hinweis für VB6-Umsteiger: Nicht-nullbasierte Arrays stehen nur noch im Rahmen der COM.Interop-Kompatibilität zur Verfügung. Während der Umstell-Phase von VB6-Programmen kann dies für Testzwecke nützlich sein. (vgl. Nicht-nullbasierte Arrays in VB.NET) Vorsicht ist bei der Verwendung des Upgrade-Assistenten geboten. Die VB6-Dimensionierung: Dim x(90 to 100, 90 to 100, 90 to 100) wird wie folgt umgestellt: ' UPGRADE_WARNING: ' Lower bound of array x was changed from 90,90,90 to 0,0,0. Dim x(100, 100, 100) As Object Die Klasse cArrayXToY ''' <summary> ''' generische Klasse zur Verwendung eines gekapselten 1D-Array ''' als nicht-nullbasiertes (ggf. auch mehrdimensionales) Array ''' </summary> ''' <typeparam name="EntryType">numerischer Typ oder String</typeparam> Public Class cArrayXToY(Of EntryType) ' Struktur für Daten einer Arraydimension Structure Limit Dim ug As Integer ' Untergrenze Dim og As Integer ' Obergrenze Dim elemente As Integer ' Länge End Structure Dim gLimits() As Limit ' Dimensionsgrenzen des Array Dim gDimFak() As Integer ' Hilfs-Faktoren zur Indexberechnung ' das gekapselte System.Array ' (-->null-basiert, ein-dimensional) Dim gArray() As EntryType ''' <summary> ''' Konstruktor (incl. Vereinbarung der Dimensionsgerenzen) ''' </summary> ''' <param name="Limits">Dimensionsgrenzen: ug1, og1, ug2, og2, ...</param> Public Sub New(ByVal ParamArray Limits() As Integer) ' Array auf 'Nichts' setzen gArray = Nothing ' Limits überprüfen If UBound(Limits) > 20 Or UBound(Limits) < 1 Then Throw New ArgumentException End If If UBound(Limits) Mod 2 <> 1 Then Throw New ArgumentException End If ' Überprüfung der Limits fortsetzen und speichern ReDim gLimits(Limits.Length \ 2 - 1) Dim j As Integer = -1, l As Integer = 1 For i As Integer = 0 To UBound(Limits) - 1 Step 2 j += 1 gLimits(j).ug = Limits(i) gLimits(j).og = Limits(i + 1) If gLimits(j).ug > gLimits(j).og Then Throw New ArgumentException End If gLimits(j).elemente = _ gLimits(j).og - gLimits(j).ug + 1 l *= gLimits(j).elemente Next i ' gekapseltes 1D-Array in der angeforderten Größe dimensionieren ReDim gArray(l - 1) ' Zu überspringende Elementzahl pro Indexwert einer Dimension ' => Multiplikation der Elementzahl aller höheren Dimensionen ReDim gDimFak(UBound(gLimits)) For i As Integer = 0 To UBound(gLimits) gDimFak(i) = 1 For k As Integer = i + 1 To UBound(gLimits) gDimFak(i) *= gLimits(k).elemente Next k Next i End Sub ''' <summary> ''' Integrierte LBOUND-Funktion: Untergrenze der Dimension ''' </summary> ''' <param name="Dimension">Dimension?</param> ''' <returns>Untergrenze</returns> Public Function Lbd(Optional ByVal Dimension As Integer = 0) As Integer If IsNothing(gArray) Then Throw New NullReferenceException End If If Dimension > _ Microsoft.VisualBasic.UBound(gLimits) Then Throw New RankException End If Return gLimits(Dimension).ug End Function ''' <summary> ''' Integrierte UBOUND-Funktion: Obergrenze der Dimension ''' </summary> ''' <param name="Dimension">Dimension?</param> ''' <returns>Obergrenze</returns> Public Function Ubd( _ Optional ByVal Dimension As Integer = 0) As Integer If IsNothing(gArray) Then Throw New NullReferenceException End If If Dimension > Microsoft.VisualBasic.UBound(gLimits) Then Throw New RankException End If Return gLimits(Dimension).og End Function ''' <summary> ''' Standardeigenschaft: Zuweisung oder Abfrage ''' eines Arrayelements ''' </summary> ''' <param name="ind1">Index 1. Dimension</param> ''' <param name="Indices">Indices weiterer Dimensionen</param> ''' <value>zuzuweisender Wert</value> ''' <returns>abgefragter Wert</returns> Default Public Property Value(ByVal ind1 As Integer, _ ByVal ParamArray Indices() As Integer) As EntryType ' Nicht wundern: Da eine Standardeigenschaft nicht ' nur ein ParamArray als Parameter besitzen darf, ' ist der erste Array-Index 'ausgelagert' worden Get If IsNothing(gArray) Then Throw New NullReferenceException End If Return gArray(Get1D_Index(ind1, Indices)) End Get Set(ByVal value As EntryType) If IsNothing(gArray) Then Throw New NullReferenceException End If gArray(Get1D_Index(ind1, Indices)) = value End Set End Property Private Function Get1D_Index(ByVal ind1 As Integer, _ ByVal ParamArray Indices() As Integer) As Integer ' Umrechnung der Indices auf das korrespondierende ' Element des internen eindimensionalen Arrays ' Indices auf Gültigkeit prüfen Dim i As Integer If UBound(Indices) <> UBound(gLimits) - 1 Then Throw New RankException End If If ind1 < gLimits(0).ug Or ind1 > gLimits(0).og Then Throw New IndexOutOfRangeException End If For i = 0 To UBound(Indices) If Indices(i) < gLimits(i + 1).ug Or _ Indices(i) > gLimits(i + 1).og Then Throw New IndexOutOfRangeException End If Next i ' Berechnung des 1D-Index unter Verwendung ' der dimensionalen Index-Multiplikatoren Dim ind As Integer = 0 '= ind1 * fak(0) ind = gDimFak(0) * (ind1 - gLimits(0).ug) For i = 1 To UBound(gLimits) ind += (gDimFak(i) * (Indices(i - 1) - gLimits(i).ug)) Next i Return ind End Function End Class Anwendungsbeispiel: ArrayXToY_Demo Private Sub ArrayXtoY_Demo() ' Die generische Klasse 'ArrayXtoY erlaubt ' ' die Verwendung verschiedener Datentypen ' Erstellung Vier-dimensionaler Arrays: Dim str As New cArrayXToY(Of String) _ (-1, 5, -2, 6, -3, 7, -8, -4) Dim dbl As New cArrayXToY(Of Double) _ (-1, 5, -2, 6, -3, 7, -8, -4) Dim shrt As New cArrayXToY(Of Short) _ (-1, 5, -2, 6, -3, 7, -8, -4) Dim z As Integer z = -1 For i As Integer = str.Lbd(0) To str.Ubd(0) For k As Integer = str.Lbd(1) To str.Ubd(1) For l As Integer = str.Lbd(2) To str.Ubd(2) For m As Integer = str.Lbd(3) To str.Ubd(3) z += 1 ' Zuweisung auf akt. Array-Element str(i, k, l, m) = CStr(z) dbl(i, k, l, m) = z ' Erweiterungskonv. shrt(i, k, l, m) = CShort(z) ' expl. Konv. Next m Next l Next k Next i z = -1 For i As Integer = dbl.Lbd(0) To dbl.Ubd(0) For k As Integer = dbl.Lbd(1) To dbl.Ubd(1) For l As Integer = dbl.Lbd(2) To dbl.Ubd(2) For m As Integer = dbl.Lbd(3) To dbl.Ubd(3) z += 1 ' Prüfabfrage des akt. Array-Elements If str(i, k, l, m) <> CStr(z) Then Stop If dbl(i, k, l, m) <> z Then Stop If shrt(i, k, l, m) <> z Then Stop Next m Next l Next k Next i End Sub Dieser Tipp wurde bereits 10.434 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevZIP40 Pro DLL Zippen und Unzippen wie die Profis! Mit nur wenigen Zeilen Code statten Sie Ihre Anwendungen ab sofort mit schnellen Zip- und Unzip-Funktionen aus. Hierbei lassen sich entweder einzelnen Dateien oder auch gesamte Ordner zippen bzw. entpacken. Tipp des Monats April 2024 Skyfloy Chart von Microsoft und dazu noch gratis Tutorial für Microsoft Chart Controls für Microsoft .NET Framework 3.5 TOP Entwickler-Paket TOP-Preis!! Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR... |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |