Rubrik: Variablen/Strings · Array/ArrayList | VB-Versionen: VB.NET | 16.02.05 |
Beliebige Daten aus einer ArrayList rausholen Wie greift man auf in einer ArrayList gespeicherte Daten (Klasseninstanzen) zu? | ||
Autor: David Mertner | Bewertung: | Views: 35.905 |
ohne Homepage | System: Win2k, WinXP, Win7, Win8, Win10, Win11 | kein Beispielprojekt |
Als ich das erste mal die neuen Objekte der Collection-Klasse ausprobiert habe, fragte ich mich, wie man die Daten denn jetzt eigentlich wieder aus diesen ominösen Strukturen herausbekommt.
Prinzipiell kann man da ja beliebige Objekte abspeichern, doch wie greift man nun darauf zu?
Da ich annehme, dass dies auch anderen Leuten Probleme bereiten könnte, habe ich mich entschieden, diese Hilfe zu verfassen.
Im Beispiel verwende ich zwar ausschließlich die sehr praktische ArrayList, wobei die anderen Collection-Objekte jedoch ähnlich funktionieren.
Zum Problem:
Angenommen ich habe eine Klasse, von der ich verschiedene Instanzen in einer Liste abspeichern will - soll ja hin und wieder vorkommen. ;)
Das ist im Prinzip alles kein Problem, doch was fange ich jetzt nach dem Erstellen mit dem ArrayList-Objekt an?!?
Wenn man da in gewohnter Manier "Liste.item(0)." eintippt und darauf wartet, dass die darin enthaltenen Elemente bzw. deren Variablen angezeigt werden, dann hat man Pech! Da kommt nämlich nichts! Der durchschnittliche VB'ler wird sich da (zu Recht) denken: "Ja, da ist halt nix drin, was man abrufen könnte!"
Tja, das ist leider falsch. Die Daten sind schon drin, man muss nur einen kleinen Trick anwenden.
Doch zuerst einmal ein bisserl Code.
Eine einfache Testklasse:
Public Class Bundesland Private Bevölkerung As Long Dim Hauptstadt As String Public Fläche As Integer Public Sub New(ByVal lBevölkerung As Long, ByVal iFläche As Integer, ByVal sHauptstadt As String) Bevölkerung = lBevölkerung Fläche = iFläche Hauptstadt = sHauptstadt End Sub Public Sub New() End Sub Public Function Dichte() As Single Dichte = Bevölkerung / Fläche End Function End Class
Der Code zum Belegen der Liste folgt im Weiteren:
' 2 Bundesländer erstellen Dim Bayern As New Bundesland(12100000, 70352, "München") Dim BadenWürtemberg As New Bundesland(10400000, 35752, "Stuttgart") ' 2 Bundesländer speichern Dim Liste As New ArrayList Liste.Add(Bayern) Liste.Add(BadenWürtemberg) ' Jetzt die Daten abrufen For i = 0 To Liste.Count - 1 ' MsgBox(Liste.Item(i).Bevölkerung) -> geht nicht, da private!! ' MsgBox(Liste.Item(i).Hauptstadt) -> geht nicht, da ebenfalls private!! ' Dim in Klassendefinition == private-Deklaration MsgBox(Liste.Item(i).Fläche) 'funktioniert MsgBox(Liste.Item(i).dichte) 'funktioniert Next
Wie wir sehen, können wir auf die Daten ganz einfach dadurch zugreifen, indem wir in der Klassendefinition nachschauen, welche Elemente es gibt und dann tippen wir die gnadenlos ein. Wie im Code bereits vermerkt, funktioniert dieses Vorgehen bei privaten Mitgliedervariablen natürlich nicht!
(Anmerkung: das gezeigte Vorgehen klappt bei der Schwestersprache C# übrigens nicht!)
Es gibt jedoch noch eine andere Methode, um die abrufbaren Daten etwas schöner zu bekommen (ohne dass man extra in der Klassendefinition nachschauen muss):
For i = 0 To Liste.Count - 1 Dim Temp As New Bundesland ' (1) Temp = Liste.Item(i) ' (2) MsgBox(Temp.Fläche) Next
Was geschieht hier?
Nun, wir erstellen uns eine temporäre Klasseninstanz ohne Initialisierung (1), der wir ein Element der Liste zuweisen (2), d.h. Temp enthält nun genau die abgespeicherte Klasseninstanz, auf die wir wie gewohnt zugreifen können:
Nach Eingabe von "Temp." klappt die bekannte Liste auf, in der folgendes steht:
Dichte
Fläche
GetType ' gehört eigentlich nicht zur Bundesland-Klasse, sondern ist geerbt
Schwierig wird es, wenn in der Liste Instanzen verschiedener Klassen abgespeichert sind, denn dann haben wir sowohl mit der einen als auch mit der anderen Methode ein Problem.
Neue Klasse:
Public Class Land Public BruttoSozialProdukt As Long Public Sub New(ByVal BS As Long) BruttoSozialProdukt = BS End Sub Public Sub New() End Sub End Class
Der geänderte Belegungscode lautet wie folgt:
' 2 Bundesländer erstellen Dim Bayern As New Bundesland(12100000, 70352, "München") Dim BadenWürtemberg As New Bundesland(10400000, 35752, "Stuttgart") Dim Deutschland As New Land(3240) ' 2 Bundesländer speichern Dim Liste As New ArrayList Liste.Add(Bayern) Liste.Add(BadenWürtemberg) Liste.Add(Deutschland) For i = 0 To Liste.Count - 1 Dim NamederKlasse As String = Liste.Item(i).GetType().Name.ToString() If (NamederKlasse.Equals("Bundesland")) Then Dim Temp As New Bundesland Temp = Liste.Item(i) MsgBox(Temp.Fläche) End If If (NamederKlasse.Equals("Land")) Then Dim Temp As New Land Temp = Liste.Item(i) MsgBox(Temp.BruttoSozialProdukt) End If Next
Wir lösen das Problem dadurch, indem wir einfach nachschauen, welcher Typ die gespeicherte Klasseninstanz entspricht und dann dynamisch darauf reagieren. Wenn wir natürlich überhaupt nicht wissen, welche Daten wir in der ArrayList erwarten können, dann macht es keinen Sinn, irgendwas anzusprechen (in diesem Fall tun wir gar nichts).
Ich hoffe mit den gezeigten Techniken ein bisschen geholfen zu haben. Die größte Schwierigkeit für mich war die Wahl des Betreffs
"Arbeiten mit der ArrayList" war mir für das spezielle Thema zu allgemein und ansonsten fiel mir auch nix griffiges ein ...