Benutzer mit den meisten Antworten
Arraylist C#

Frage
-
Hallo,
ich habe nur Arraylists erlernt, und wollte diese in meinen nicht funktionierden Terminplaner implemetieren. Doch dabei passiert dies :
ArrayList events = new ArrayList(); public void ManageEvent(string mode,int day, int month, int hour, int minute, string name, string description) { Terminplaner planmanage = new Terminplaner(); if (mode == "new") { //Hier funktioniert noch alles// events.Add(new Event(day, minute, hour, minute, name, description)); } else { Console.WriteLine("Für welchen Termin sollen Informationen aufgerufen werden?"); string input = Console.ReadLine(); foreach(object request in events) { //Ich kann nicht auf die Eigenschaften zugreifen, somit auch nicht die Namen abgleichen.// } } }
Habe ich in der Array-List irgendetwas falsch gemacht?
LG
Antworten
-
Hi,
eine ArrayList ist das Primitivste unter den Listen. Eine ArrayList arbeitet mit Elementen vom Typ Object. Deshalb kann einer ArrayList jedes beliebige Objekt hinzugefügt werden, da jeder Typ per Definition letztendlich vom Typ Object erbt. Diese Universalität hat seinen Preis. Wenn ein Element aus einer ArrayList genutzt werden soll, dann bekommt man nur einen Verweis vom Typ "object". Damit kann man nur sehr wenig anfangen. Man kann ermitteln, von welchem Typ dieses Element wirklich ist (Methode GetType) oder man weiß es anhand des implementierten Algorithmus' von welchem Typ das Element sein muss.Um dann auf alle Innereien des Elementes zuzugreifen, muss man sich einen Verweis vom passenden Typ besorgen. Dazu dient das Typecasting, um aus einem Basistyp (im konkreten Fall 'object') einen davon abgeleiteten Zieltyp zu machen, mit dem dann der Zugriff auf alle Innereien möglich ist. Das hört sich kompliziert an, ist aber in der Praxis recht einfach. Das Element in der ArrayList ist ein Verweis auf einen Speicherplatz, wo sich das Element befindet. Beim Typecasting wird dieser Verweis einfach nur in die Ziel-Variable kopiert, wobei zusätzlich die Laufzeitumgebung prüft, ob das auch wirklich zulässig ist.
Nach diesem kurzen Exkurs heißt das für Deinen Code, dass Du in der foreach-Schleife für jedes Element erst mal ein Typecasting auf den Typ "Event' ausführen musst, z.B. so:
Console.WriteLine("Für welchen Termin sollen Informationen aufgerufen werden?"); string input = Console.ReadLine(); foreach(Event request in events) { request. .... }
Das funktioniert, solange alle Elemente in der ArrayList vom Typ 'Event' sind (bzw. eines vom Typ 'Event' geerbten Types).
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Florian Haupt Donnerstag, 20. August 2015 06:31
- Als Antwort markiert R3turnz Donnerstag, 20. August 2015 08:21
Alle Antworten
-
Hi,
eine ArrayList ist das Primitivste unter den Listen. Eine ArrayList arbeitet mit Elementen vom Typ Object. Deshalb kann einer ArrayList jedes beliebige Objekt hinzugefügt werden, da jeder Typ per Definition letztendlich vom Typ Object erbt. Diese Universalität hat seinen Preis. Wenn ein Element aus einer ArrayList genutzt werden soll, dann bekommt man nur einen Verweis vom Typ "object". Damit kann man nur sehr wenig anfangen. Man kann ermitteln, von welchem Typ dieses Element wirklich ist (Methode GetType) oder man weiß es anhand des implementierten Algorithmus' von welchem Typ das Element sein muss.Um dann auf alle Innereien des Elementes zuzugreifen, muss man sich einen Verweis vom passenden Typ besorgen. Dazu dient das Typecasting, um aus einem Basistyp (im konkreten Fall 'object') einen davon abgeleiteten Zieltyp zu machen, mit dem dann der Zugriff auf alle Innereien möglich ist. Das hört sich kompliziert an, ist aber in der Praxis recht einfach. Das Element in der ArrayList ist ein Verweis auf einen Speicherplatz, wo sich das Element befindet. Beim Typecasting wird dieser Verweis einfach nur in die Ziel-Variable kopiert, wobei zusätzlich die Laufzeitumgebung prüft, ob das auch wirklich zulässig ist.
Nach diesem kurzen Exkurs heißt das für Deinen Code, dass Du in der foreach-Schleife für jedes Element erst mal ein Typecasting auf den Typ "Event' ausführen musst, z.B. so:
Console.WriteLine("Für welchen Termin sollen Informationen aufgerufen werden?"); string input = Console.ReadLine(); foreach(Event request in events) { request. .... }
Das funktioniert, solange alle Elemente in der ArrayList vom Typ 'Event' sind (bzw. eines vom Typ 'Event' geerbten Types).
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Florian Haupt Donnerstag, 20. August 2015 06:31
- Als Antwort markiert R3turnz Donnerstag, 20. August 2015 08:21
-
Erstmal danke für die Erklärung, bin nur teilweise mitgekommen. request stellt also nur einen verweis aus dem Stack in den Heap dar? Mit dem Typecasting wird der Inhalt direkt in request kopiert? Was ich nicht verstehe ist:
Wieso kann ich von dem Verweiß aus nicht auf den Speicherplatz zugreifen. Es ist ja ein Verweis....
Jetzt kann ich zwar auf die Variablen zugreifen, aus irgendeinem Grund funktioniert es immer noch nicht:
public void ManageEvent(string mode,int day, int month, int hour, int minute, string name, string description) { Terminplaner planmanage = new Terminplaner(); if (mode == "new") { events.Add(new Event(day, minute, hour, minute, name, description)); } else { Console.WriteLine("Für welchen Termin sollen Informationen aufgerufen werden?"); string input = Console.ReadLine(); foreach(Event request in events) { if (request.Name == input) { request.ToString(); Console.WriteLine("Die Informationen werden ausgegeben."); } else if (request == null) { Console.WriteLine("Der Termin ist leer."); } else { Console.WriteLine("Dein eingegebner Termin ist nicht vorhanden."); } }
Ich habe überall extra ein Ouput in der Konsole hinzugefügt, beim asuführen wird aber kein Output zurückgegeben...
LG
- Bearbeitet R3turnz Donnerstag, 20. August 2015 08:49
-
Hi,
im .NET ist eine Variable entweder vom Wertetyp oder vom Verweis.Beim Wertetyp steht der Inhalt direkt auf dem Speicherplatz der Variablen. Das sind beispielsweise int-Werte.
Beim Verweistyp steht auf dem Speicherplatz der Variablen nur die Adresse (Verweis) auf einen Speicherplatz, wo sich das Objekt befindet. Dieser Verweis (Adresse) kann man sich wie eine Basisadresse (Startadresse) für das Objekt vorstellen. Die einzelnen Werte im Objekt stehen dann an entsprechenden Verschiebungen zur Basisadresse. Wenn mittels einer Verweisvariablen auf den Inhalt eines Objektes zugegriffen wird, wird intern aus der Basisadresse und der Verschiebung der Platz (Adresse) ermittelt, wo sich der gewünschte Wert befindet. Der Compiler kann diesen Platz (Basisadresse + Verschiebung) nur für den konkreten Typ der Variablen ermitteln. Wenn die Variable aber von einem Typ ist, der nur einen Teil des Objektes kennt, kann der Compiler die weiteren Teile nicht ansprechen, auch, wenn es diese gibt. Diese Situation entsteht immer dann, wenn vererbt wird. Die Basisklasse kennt üblicherweise weniger als die davon erbende Klasse.
Für Dein Beispiel bedeutet das, dass Du eine Klasse "Event" hast, die von der Klasse "object" erbt. Der ArrayList fügst Du Verweise auf Deine Elemente hinzu. Die ArrayList kann nur Elemente vom "object" verwalten, auch wenn Deine Elemente vom Typ "Event" viel mehr bieten. Das funktioniert, weil die Mutter aller Klassen das "object" ist. Beim Auslesen bekommt du einen Verweis auf ein Element vom Typ "object". Damit kannst Du alles machen, was der Typ "object" kann, z.B. ToString oder GetType. Mehr kannst Du nicht machen, obwohl der Verweis auf Dein Element zeigt, was vom Typ "Event" ist und noch viele weitere Eigenschaften hat.
Mit dem TypeCasting teilst Du der Laufzeitumgebung mit, dass Du ab sofort den Verweis nicht mehr als Verweis auf ein Element vom Typ 'object' nutzen willst, sondern als Verweis auf ein Element vom Typ "Event". Die Laufzeitumgebung prüft, ob das auch rechtens ist. Damit wird die Typsicherheit gewährleistet im Gegensatz zu früheren System, wo z.B. 4 Byte übergeben wurden und der Empfänger diese 4 Byte als Festkommazahl, Gleitkommazahl oder 4 Zeichen interpretieren konnte und damit auch schnell mal einen Programmabsturz erzeugt hat.
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks