Die Überprüfung, ob zwei System.Arrays gleich sind, ist in Visual Basic relativ einfach, falls die Elemente die IComparable-Schnittstelle implementiert haben. Das trifft z.B. auf alle sog. Primitiven Typen zu. Man überprüft zunächst die Rahmenkonstruktion der Arrays (Nothing, Type, Rank, Bounds). Die Nothing-Prüfung ist erforderlich, weil Array-Variable Referenztypen sind, auch wenn die Elemente aus einem Werttyp bestehen. Findet man beim Vergleich eine identische Rahmenkonstruktion, überträgt man die Array-Elemente jeweils in ein eindimensionales Object-Array, um die Rank-spezifische Indizierung loszuwerden (per Linq / ToArray-Erweiterung). Der Typ der einzelnen Array-Elemente bleibt dabei erhalten, es ändert sich nur die Array-Variable. Durch eine einfache Schleife können die korrespondierenden Array-Elemente miteinander verglichen werden (Nothing, Type, Content). Die Nothing- und Type-Checks sind erforderlich, weil Arrays Element-Referenzen auf alle möglichen Strukturen, Objekte und auch auf Nothing enthalten können. Die Erweiterungen 'IsEqual' heften sich an Arrays, deren Array-Variablen-Deklaration signalisiert, dass die Comparable-Schnittstelle implementiert ist. Sie erlauben als Parameter nur Arrays, die die gleiche Zahl von Dimensionen aufweisen (1-3). Die Erweiterung 'Equality' heftet sich an alles, was nach einem System.Array aussieht. Als Parameter wird ebenfalls jedes System.Array zur Entwicklungszeit akzeptiert. Falls die Array-Elemente die IComparable-Schnittstelle nicht implementiert haben, wird eine Ausnahme ausgelöst. Einige Beispiele: Module modArrayEqual_Exempl
Public Sub IsArrayEqual_Exempl() Dim i1(), i2() As Short If i1.IsEqual(i2) Then Stop ' ---> Stop erreicht, weil beide Nothing sind Dim i3(0) As Short If Not i1.IsEqual(i3) Then Stop ' ---> Stop erreicht, weil 'i3' nicht nothing ist Dim i4(0) As Integer If Not i3.Equality(i4) Then Stop ' ---> Stop erreicht, weil unterschiedliche Array-Typen vorliegen Dim i5(0, 0) As Short If Not i3.Equality(i5) Then Stop ' ---> Stop erreicht, weil unterschiedliche Dimensionen vorliegen Dim i6(0, 1) As Short If Not i5.IsEqual(i6) Then Stop ' ---> Stop erreicht, weil unterschiedliche Grenzen vorliegen Dim i7(0, 1) As Short i7(0, 0) = 1 If Not i6.IsEqual(i7) Then Stop ' ---> Stop erreicht, weil unterschiedliche Arrayinhalte vorliegen Dim t1 As String = "Test1", t2 As String = "TEST1" If Not t1.ToCharArray.IsEqual(t2.ToCharArray) Then Stop ' ---> Stop erreicht, weil case-sensitiver Vergleich vorgenommen wird Dim c1(0) As Object, c2(0) As Object c1(0) = 1% : c2(0) = 1.0# If Not c1.Equality(c2) Then Stop ' ---> Stop erreicht, weil Elementtyp Integer <> Double ist Dim oa1(10), oa2(10) As Object oa1(0) = CShort(0) oa1(1) = 1 : oa1(2) = 2.0! : oa1(3) = 3.0# oa1(4) = "x"c oa1(5) = CByte(5) : oa1(6) = CULng(6) oa1(7) = 1.0# For i As Integer = 0 To 10 : oa2(i) = oa1(i) : Next i oa2(7) = CDbl(oa1(7)) + (1000.0# * Double.Epsilon) If oa1.Equality(oa2) Then Stop ' ---> Stop wird erreicht, weil beide Arrays als gleich gelten ' Der Unterschied ist im Datentyp nicht darstellbar Dim p1(5) As cPersonalDaten Dim p2(5) As cPersonalDaten p1(0) = New cPersonalDaten("Maier", "Hans", "Schlosser") p1(1) = New cPersonalDaten("Müller", "Georg", "Pfoertner") p1(2) = New cPersonalDaten("Schneider", "Eduard", "Maschinist") p1(4) = New cPersonalDaten("Gerber", "Harald", "Buchhalter") For i As Integer = 0 To p1.Length - 1 If Not p1(i) Is Nothing Then With p1(i) ' echte Kopien der Instanzen durch Konstruktor erstellen p2(i) = New cPersonalDaten(._Name, ._Vorname, ._Position) End With End If Next i If p1.IsEqual(p2) Then Stop ' ---> Stop wird erreicht, weil alle Elemente identisch sind, ' auch die Nothing-Elemente !!! End Sub ''' <summary>Demoklasse, implementiert IComparable für ''' Vergleich von Instanzen (nicht zum Sortieren geeignet!!) ''' </summary> Private Class cPersonalDaten Implements IComparable ' öffentliche Membervariablen Public _Vorname As String Public _Name As String Public _Position As String ''' <summary>Demoklasse, implementiert IComparable für ''' Vergleich von Instanzen (nicht zum Sortieren geeignet!!) ''' </summary> Public Sub New(ByVal name As String, _ ByVal vorname As String, _ ByVal position As String) _Name = name _Vorname = vorname _Position = position End Sub Public Function CompareTo(ByVal obj As Object) As Integer _ Implements System.IComparable.CompareTo If Me.Equals(obj) Then Return 0 Dim v As cPersonalDaten = CType(obj, cPersonalDaten) With v If _Vorname <> ._Vorname Then Return -1 If _Name <> ._Name Then Return -1 If _Position <> ._Position Then Return -1 End With Return 0 End Function End Class End Module Option Strict On Option Explicit On Option Infer Off Imports System Imports System.Math Imports System.Linq.Enumerable Module modIsArrayEqual ''' <summary> ''' Prüfung der Gleichheit von zwei System.Arrays ''' Vergleich: Rank, Bounds, Type, Content (per IComparable) ''' </summary> ''' <param name="arr1">1. zu vergleichendes Array</param> ''' <param name="arr2">2. zu vergleichendes Array</param> ''' <returns>true falls identisch, sonst false</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function IsEqual(Of T As IComparable) _ (ByVal arr1 As T(), ByVal arr2 As T()) As Boolean Return Equality(arr1, arr2) End Function ''' <summary> ''' Prüfung der Gleichheit von zwei System.Arrays ''' Vergleich: Rank, Bounds, Type, Content (per IComparable) ''' </summary> ''' <param name="arr1">1. zu vergleichendes Array</param> ''' <param name="arr2">2. zu vergleichendes Array</param> ''' <returns>true falls identisch, sonst false</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function IsEqual(Of T As IComparable) _ (ByVal arr1 As T(,), ByVal arr2 As T(,)) As Boolean Return Equality(arr1, arr2) End Function ''' <summary>Prüfung der Gleichheit von zwei System.Arrays ''' Vergleich: Rank, Bounds, Type, Content (per IComparable) ''' </summary> ''' <param name="arr1">1. zu vergleichendes Array</param> ''' <param name="arr2">2. zu vergleichendes Array</param> ''' <returns>true falls identisch, sonst false</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function IsEqual(Of T As IComparable) _ (ByVal arr1 As T(,,), ByVal arr2 As T(,,)) As Boolean Return Equality(arr1, arr2) End Function ''' <summary>Prüfung der Gleichheit von zwei System.Arrays ''' Vergleich: Rank, Bounds, Type, Content (per IComparable) ''' </summary> ''' <param name="arr1">1. zu vergleichendes Array</param> ''' <param name="arr2">2. zu vergleichendes Array</param> ''' <returns>true falls identisch, sonst false</returns> <System.Runtime.CompilerServices.Extension()> _ Public Function Equality _ (ByVal arr1 As System.Array, ByVal arr2 As System.Array) As Boolean Dim iarr1(), iarr2() As Object Dim typ1, typ2 As System.Type Dim el1, el2 As IComparable ' Nothing = Nothing If arr1 Is Nothing And arr2 Is Nothing Then Return True ' Ein einzelner Nothing-Parameter führt immer zu 'false' If arr1 Is Nothing Or arr2 Is Nothing Then Return False ' Identisches Objekt? If arr1.Equals(arr2) Then Return True ' Datentyp und Rank der Arrays vergleichen? If Not arr1.GetType.Equals(arr2.GetType) Then Return False ' Index-Obergrenzen vergleichen For i As Integer = 0 To arr1.Rank - 1 If arr1.GetUpperBound(i) <> arr2.GetUpperBound(i) Then Return False Next i ' Array-Elemente per Linq in ' eindimensionale Arrays eintragen iarr1 = (From x In arr1).ToArray iarr2 = (From x In arr2).ToArray For i As Integer = 0 To iarr1.Length - 1 ' Vergleich der Array-Elemente (IComparable) If iarr1(i) Is Nothing Or iarr2(i) Is Nothing Then ' Vergleich von Nothing-Elementen If iarr1(i) Is Nothing And Not iarr2(i) Is Nothing Then Return False If Not iarr1(i) Is Nothing And iarr2(i) Is Nothing Then Return False Else ' Typ der korrespondierenden Array-Elemente typ1 = iarr1(i).GetType : typ2 = iarr2(i).GetType ' Gleicher Typ? If Not typ1.Equals(typ2) Then Return False ' Gleicher Inhalt? el1 = CType(iarr1(i), IComparable) el2 = CType(iarr2(i), IComparable) If el1.CompareTo(el2) <> 0 Then Return False End If Next i Return True End Function End Module Dieser Tipp wurde bereits 19.703 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 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. |
vb@rchiv CD Vol.6 Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! Online-Update-Funktion Entwickler-Vollversionen u.v.m. Tipp des Monats März 2024 Dieter Otter UTF-8 Konvertierung von Dateien und Strings VB6 selbst verfügt über keine Funktionen zur UTF-8 Konvertierung von Daten. Mit Hilfe des ADODB.Stream-Objekts lassen sich diese fehlenden Funktionen aber schnell nachrüsten. Neu! sevPopUp 2.0 Dynamische Kontextmenüs! Erstellen Sie mit nur wenigen Zeilen Code Kontextmenüs dynamisch zur Laufzeit. Vordefinierte Styles (XP, Office, OfficeXP, Vista oder Windows 8) erleichtern die Anpassung an die eigenen Anwendung... |
||||||||||||||||
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. |