vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
SEPA-Dateien erstellen inkl. IBAN-, BLZ-/Kontonummernprüfung  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Variablen/Strings · Array/ArrayList   |   VB-Versionen: VB.NET14.05.07
Flexible Array-Übergabe an Funktionen (VB 2005)

Unterschiedlich deklarierte Arrays als OBJECT-Parameter an eine Funktion übergeben

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  18.743 
ohne HomepageSystem:  WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11kein Beispielprojekt 

Manchmal möchte man Funktionen erstellen, die als Parameter übergebene Arrays verarbeiten, die unterschiedliche Datentypen und/oder eine unterschiedliche Zahl von Dimensionen aufweisen können. (Man beachte den Unterschied zwischen mehrdimensionalen und 'verzweigten' Arrays = Arrays, die Arrays als Felder enthalten. Die sind mit der CLS nicht kompatibel !!)

Zu denken ist z.B. an Routinen, die Berechnungen mit Gleitkomma-Werten durchführen, wobei es egal sein soll, ob die Daten in einem Single-, Double- oder Decimal-Array vorliegen.

Auch die Array-Dimensionen können bei manchen Anwendungen variieren. Daten könnten in einem Programm an einer Stelle zweckmäßig als Vektoren ( = eindimensionale Arrays), woanders als Matrix ( = zweidimensionales Array) oder als Kubus ( = dreidimensionales Array) organisiert sein.

Funktionen können durch die Verwendung von OBJECT bei der Parameter-Übergabe eines Array entsprechend flexibel gestaltet werden. In diesem Fall wird erst zur Laufzeit des Programms festgelegt, welche Art von Objekt an die Funktion als Parameter übergeben wird (späte Bindung).

Die Verwendung des OBJECT-Parameters hat einige Auswirkungen:

  • Die OPTION STRICT ON - Anweisung darf in dem Modul nicht enthalten sein, das Funktionen mit OBJECT-Parametern enthält, weil sie Zugriffe auf die spezifischen Methoden und Eigenschaften von als OBJECT übergebenen Objekten nicht duldet. (Aber: OPTION EXPLICIT ON kann verwendet werden)
  • Die IntelliSense der VB-Entwicklungsumgebung funktioniert bei OBJECT-Parametern nur eingeschränkt. Angezeigt werden nur die allgemeinen OBJECT-Eigenschaften und Methoden.
  • Die 'späte Bindung' erlaubt keine Typ-Überprüfung beim Kompilieren (die sog. 'lose Typisierung') und sie beansprucht mehr Rechenzeit bei der Code-Ausführung.
  • Die Funktionen sollten vor der Verwendung von Methoden und Eigenschaften der OBJECT-Parameter zunächst explizit prüfen, ob überhaupt ein Objekt und ob eine Instanz des erwarteten Objekts (d.h. in unserem Fall: ein Array) übergeben worden ist.

Dazu die VB-Doku:
Die späte Bindung erfordert zusätzliche Ausführungszeit. Außerdem wird der Code auf die Methoden und Eigenschaften der Klasse beschränkt, die Sie zuletzt zugewiesen haben. Wenn der Code auf Member einer anderen Klasse zuzugreifen versucht, kann es dadurch zu Laufzeitfehlern kommen.

Weitere Hinweise:
Es ist möglich, die Zahl der Dimensionen und die Obergrenze der Dimensionen eines als OBJECT übergebenen Array in der gerufenen Funktion (lokal) zu ändern (REDIM-Anweisung) - falls das Array aber BYREF übergeben worden ist, entsteht bei der Rückgabe gewöhnlich ein Fehler.

Der Datentyp des als OBJECT übergebenen Array kann in der gerufenen Funktion nicht explizit geändert werden, weil keine DIM-Anweisung für Parameter zulässig ist.

VB-Doku: Traversieren von Arrays (For Each ... Next).
Da die Array-Klasse die IEnumerable-Schnittstelle implementiert, machen alle Arrays die GetEnumerator-Methode verfügbar. Das bedeutet, dass Sie ein Array mit einer 'For Each ...Next'Schleife traversieren können. Allerdings können Sie die Arrayelemente NUR LESEN, nicht ändern. .... Die Traversalreihenfolge wird dabei nicht durch Visual Basic festgelegt, sondern von der MoveNext-Methode des Enumerationsobjekts. .... Das von 'GetEnumerator' zurückgegebene Enumerationsobjekt ermöglicht es Ihnen NICHT, die Auflistung durch Hinzufügen, Löschen, Ersetzen oder Neuordnen von Elementen ZU ÄNDERN (Hervorhebungen - der Verf.)

Bei mehrdimensionalen Arrays ergibt sich die Reihenfolge der durch die interne MoveNext-Methode traversierten Elemente durch Hochsetzen des Index der letzten (höchsten) Dimension usw.

Beispiel (Funktion 'Array_Info'):

Die als Bespiel beigefügte Funktion 'Array_Info' akzeptiert im OBJECT-Parameter 'ARR' ein Array aus einem der Gleitkomma-Datentypen, das beliebig viele Dimensionen umfassen kann.
Bei Übergabe eines ungeeigneten Objekts wird eine entsprechende Meldung und 'false' zurückgeliefert.

Die optionalen Parameter informieren über den Datentyp des Array, die Gesamtzahl der Array-Felder, die Anzahl der Array-Dimensionen, die kleinste und die größte Ausprägung eines Arrayfeld-Wertes.
Liegen in einem oder mehreren Feldern die Ausprägungen 'PositiveInfinity' oder 'NegativeInfinity' vor
(nur bei SINGLE, DOUBLE möglich), enthalten die Parameter MINIMUM bzw. MAXIMUM diese IEEE-Sonderwerte.

Die Anzahl der Array-Felder, die positive (>0) bzw. negative Werte aufweisen, wird ermittelt und - optional - zurückgegeben. Felder, die Infinity-Werte enthalten, werden jeweils mitgezählt.

Der optionale Parameter SUMME enthält die Summe der Ausprägungen aller Array-Felder.
Sollte bei der Summation die zulässige numerische Ausprägung des Datentyps DOUBLE über- oder unterschritten werden, steht in SUMME der IEEE-Sonderwert 'NaN' ('not a number').

Man beachte, dass die Parameter MINIMUM, MAXIMUM, SUMME vom Typ Double sind - also nicht als OBJECT übergeben werden - , und unabhängig vom Datentyp des übergebenen Array Double-Werte zurückgeben.

Sollte in mindestens einem Array-Feld des Parameters 'ARR' ein 'NaN'-Wert ermittelt werden (nur möglich bei SINGLE, DOUBLE) , wird von der Funktion 'ARRAY_INFO' ein auffangbarer Fehler ausgelöst. Zu diesem Zweck habe die 'SYSTEM.Overflowexception' herangezogen.

Public Function Array_Info(ByVal arr As Object, _
  Optional ByRef DatenTyp As String = "", _
  Optional ByRef Anzahl_Felder As Long = 0, _
  Optional ByRef Anzahl_Dimensionen As Short = 0, _
  Optional ByRef Minimum As Double = 0, _
  Optional ByRef Maximum As Double = 0, _
  Optional ByRef Negative_Felder As Integer = 0, _
  Optional ByRef Positive_Felder As Integer = 0, _
  Optional ByRef Summe As Double = 0, _
  Optional ByRef Meldung As String = "") _
  As Boolean
 
 
  ' Verarbeitete Daten-Typen (Gleitkomma-Variable)
  Dim st_double As String = "SYSTEM.DOUBLE"
  Dim st_single As String = "SYSTEM.SINGLE"
  Dim st_decimal As String = "SYSTEM.DECIMAL"
 
  Dim dbl As Double      ' intern: einheitlicher Datentyp
  Dim pos As Integer     ' Stringanalyse
 
  ' Rückgabe zunächst explizit auf 'undefiniert' setzen
  DatenTyp = ""
  Anzahl_Felder = -1
  Anzahl_Dimensionen = -1
  Minimum = Double.NaN
  Maximum = Double.NaN
  Positive_Felder = -1
  Negative_Felder = -1
  Summe = Double.NaN
 
  Meldung = ""
 
  ' Ist in 'arr' ein Objekt gegeben worden?
  Try
    If arr = Nothing Then
      Meldung = "Kein Objekt verfügbar"
      Return False
    End If
  Catch
    ' muss abgefangen werden 
    ' weil der nothing-Vergleich bei 
    ' dekl. Array Fehler auslöst
  End Try
 
  ' Kennung für den Typ des übergebenen Objekts ermitteln
  Dim at As String = UCase(arr.GetType.ToString)
 
  ' Liegt in 'arr' ein Array vor , d.h. steht [] im Type}?
  pos = InStr(at, "[")
  If pos = 0 Then
    Meldung = "Das Objekt ist kein Array"
    Return False
  End If
 
  ' Datentyp des Array ermitteln
  DatenTyp = Left(at, pos - 1)
 
  ' Wird der Datentyp von 'arr' akzeptiert?
  If InStr(at, st_double) = 0 And _
    InStr(at, st_single) = 0 And _
    InStr(at, st_decimal) = 0 Then
 
    Meldung = "Der Datentyp wird nicht unterstützt"
    Return False
  End If
 
  ' Zahl der Array-Dimensionen abfragen
  Anzahl_Dimensionen = arr.Rank
  ' Zahl der Array-Felder abfragen
  Anzahl_Felder = arr.LongLength
 
  ' Kennwerte des Array-Inhaltes ermitteln
 
  ' Initialisierung der Rückgabe-Variablen
  Minimum = Double.PositiveInfinity
  Maximum = Double.NegativeInfinity
  Positive_Felder = 0
  Negative_Felder = 0
  Summe = 0
 
  ' Hier wird das Array-Objekt 'arr' als Auflistung betrachtet
  ' und es werden sukzessive alle Felder abgefragt
  ' (nur Lesezugriff ist möglich!)
  For Each field As System.Object In arr
    ' Inhalt des aktuellen Feldes in Double-Wert wandeln
    dbl = CDbl(field)
 
    If Double.IsNaN(dbl) Then
      ' nicht-numerischer Wert in einem Feld -->
      ' Funktion löst auffangbaren Fehler aus
      Throw New System.OverflowException
      Exit Function
    End If
 
    ' größten und kleinsten Wert im Array ermitteln
    ' ggf. werden Infinity-Werte ermittelt
    If dbl > Maximum Then Maximum = dbl
    If dbl < Minimum Then Minimum = dbl
 
    ' Anzahl der Felder, die positive bzw.
    ' negative Werte enthalten
    If dbl < 0 Then
      Negative_Felder += 1
    ElseIf dbl > 0 Then
      Positive_Felder += 1
    End If
 
    ' Summe der Array-Elemente ermitteln
    ' bei DOUBLE-Überlauf während der Summation: 
    ' ---> Rückgabe des IEEE-Sonderwerts 'NaN'
    Try
      If Not Double.IsNaN(Summe) Then
        ' Summation der Werte der Array-Elemente
        Summe += dbl
        ' Überlauf der Summation?
        ' --> Infinity-Wert entsteht in 'Summe'
        If Summe > Double.MaxValue Or _
          Summe < Double.MinValue Then
 
          Summe = Double.NaN
        End If
      End If
    Catch
      ' nur zur Sicherheit
      Summe = Double.NaN
    End Try
 
    ' Schleife: nächstes Arrayelement
  Next field
 
  ' alles ín Ordnung --> true
  Return True
 
End Function

Dieser Tipp wurde bereits 18.743 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!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.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
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.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel