Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Arrays mit Index und Schlüssel

Geschrieben von: Christoph Wille
Kategorie: C#

Arrays sind ein tolle Erfindung - man greift per Index bequem auf die Elemente zu. Will man nicht per Index auf ein Element zugreifen sondern per Schlüssel, dann verwendet man die Hashtable Klasse. Doch was wenn man sowohl per Index als auch Schlüssel auf Elemente zugreifen will? Auch dann wird man von .NET nicht alleine gelassen, denn es gibt die SortedList Klasse, eine Mischung aus Array und Hashtable.

1,2,3 - so einfach geht's!

Die SortedList ist also eine Mischung aus Array und Hashtable. Daß die Verwendung dadurch nicht komplizierter wird, demonstriert gleich das erste Beispiel (access.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
SortedList slDotNetLists = new SortedList();
slDotNetLists.Add("ASP.NET", "aspDEdotnet@aspfriends.com");
slDotNetLists.Add("C#", "dotnetDEcsharp@aspfriends.com");
slDotNetLists.Add("VB.NET", "dotnetDEvb@aspfriends.com");

Response.Write(slDotNetLists.GetByIndex(0).ToString() + "<br>");
Response.Write(slDotNetLists["C#"].ToString() + "<br>");
int nIndex = slDotNetLists.IndexOfKey("VB.NET");
Response.Write(slDotNetLists.GetByIndex(nIndex).ToString() + "<br>");
%>

Das Hinzufügen von Elementen funktioniert schon wie bei der Hashtable Klasse gelernt. Die Zugriffe auf die Elemente sind der interessante Part, zuerst per Index:

object objValue = slDotNetLists.GetByIndex(0);

Der Zugriff auf ein Element passiert via GetByIndex Methode. Warum nicht per Indexer, also den eckigen Klammern? Nun, die sind für den Zugriff via Schlüssel reserviert:

object objValue = slDotNetLists["C#"];

Um zu zeigen daß man auch mit der Kirche um's Kreuz zum Ziel kommen kann, habe ich noch folgende Zugriffsvariante eingebaut:

int nIndex = slDotNetLists.IndexOfKey("VB.NET");
object objValue = slDotNetLists.GetByIndex(nIndex);

Man kann den Indexwert eines Schlüssel ermitteln, und dann per GetByIndex an den Wert kommen.

Die korrekte Verwendung von foreach

Was soll man da eigentlich falsch machen können, werden sich einige fragen. Sehen wir uns einmal die Standardanwendung an (iterateforeach.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
SortedList slDotNetLists = new SortedList();
slDotNetLists.Add("ASP.NET", "aspDEdotnet@aspfriends.com");
slDotNetLists.Add("C#", "dotnetDEcsharp@aspfriends.com");
slDotNetLists.Add("VB.NET", "dotnetDEvb@aspfriends.com");

foreach (DictionaryEntry de in slDotNetLists)
{
  Response.Write(de.Key + " - " + de.Value + "<br>\r\n");
}
%>

Prinzipiell ist das in ASP.NET auch so OK, nur: der Enumerator ist nicht thread-safe. Was bedeutet das? Angenommen, ich habe eine größere Anwendung, in der ein Teil des Programms die SortedList ändert (Einträge hinzufügt oder löscht), und ein anderer die Daten listet. Was passiert, wenn während des Auflistens ein Wert herausgelöscht wird? Nun, das foreach wird möglicherweise mit einer Exception "sterben", weil ich ohne "Wissen" des Enumerators ein Element herausgelöscht habe, auf das er möglicherweise zugreifen wird.

Um dies zu verhindern, kann man die SortedList synchronisieren, das heißt sich eine thread-sichere Kopie geben lassen. Daß dies keineswegs ein grober Mehraufwand ist demonstriert iteratesynchronized.aspx:

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
SortedList slDotNetLists = new SortedList();
slDotNetLists.Add("ASP.NET", "aspDEdotnet@aspfriends.com");
slDotNetLists.Add("C#", "dotnetDEcsharp@aspfriends.com");
slDotNetLists.Add("VB.NET", "dotnetDEvb@aspfriends.com");

SortedList slSynchronized = SortedList.Synchronized(slDotNetLists);
Response.Write(slSynchronized.IsSynchronized.ToString() + "<br>");

foreach (DictionaryEntry de in slSynchronized)
{
  Response.Write(de.Key + " - " + de.Value + "<br>\r\n");
}
%>

Nur der Aufruf der statischen Methode Synchronized ist notwendig, um thread-sicher mit foreach arbeiten zu können. Die Abfrage von IsSynchronized dient eigentlich nur der Demonstration daß man leicht herausfinden kann, ob man mit einer synchronisierten SortedList arbeitet oder nicht.

Suchen in der SortedList

Oftmals möchte man sich versichern, daß bestimmte Einträge auch wirklich in der SortedList sind. Dann wird man die auch schon von der Hashtable Klasse bekannten Methoden ContainsKey und ContainsValue verwenden. Das folgende Beispiel (search.aspx) ist nichts weiter als eine leicht angepasste Version des Scripts, das ich auch schon für die Hashtable Klasse verwendet habe.

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
SortedList slDotNetLists = new SortedList();
slDotNetLists.Add("ASP.NET", "aspDEdotnet@aspfriends.com");
slDotNetLists.Add("C#", "dotnetDEcsharp@aspfriends.com");
slDotNetLists.Add("VB.NET", "dotnetDEvb@aspfriends.com");

// Anzahl der Element in der SortedList
int nElementCount = slDotNetLists.Count;

// existiert der Schlüssel?
bool bKeyCont = slDotNetLists.ContainsKey("C#");

// existiert der Wert?
bool bValueCont = slDotNetLists.ContainsValue("dotnetDEvb@aspfriends.com");

// Element korrekt suchen
if (true == bKeyCont)
{
  Response.Write(slDotNetLists["C#"].ToString());
}
%>

Updaten und Löschen

Üblicherweise befüllt man eine Collection nicht nur, sondern man möchte auch Werte ändern und sogar löschen können. Das kann die SortedList Klasse natürlich auch - wie im folgenden Beispiel gezeigt (updateremove.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
SortedList slDotNetLists = new SortedList();
slDotNetLists.Add("ASP.NET", "aspDEdotnet@aspfriends.com");
slDotNetLists.Add("C#", "dotnetDEcsharp@aspfriends.com");
slDotNetLists.Add("VB.NET", "dotnetDEvb@aspfriends.com");

// existiert der Schlüssel?
bool bKeyCont = slDotNetLists.ContainsKey("VB.NET");

// Element korrekt updaten
if (true == bKeyCont)
{
  slDotNetLists["VB.NET"] = "deadinthewater@nowhere.org";
}

// Element löschen; existiert es nicht --> Exception
slDotNetLists.Remove("VB.NET");

// und jetzt löschen wir alles
slDotNetLists.Clear();
%>

Die Methode ContainsKey ist bereits ein alter Bekannter, ebenso wie der Indexer - nur daß ich ihn hier zum Ändern des Wertes verwende. Ebenso einfach ist die Verwendung der Remove Methode, die ein einzelnes Element anhand des Schlüssels aus der SortedList entfernt. Last but not least bleibt mir die Clear Methode zu erklären: diese löscht sämtliche Elemente aus der SortedList.

Schlußbemerkung

Die SortedList Klasse ist ein weiterer Beweis dafür, daß man im Framework für fast jeden Bedarf eine bereits existierende Klasse finden kann.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Collections einmal anders: Stacks und Queues
Das foreach Statement
Debugging in der Tiefe
Die Hashtable Klasse
Sortieren mit dem IComparer Interface
Verwendung von Arrays in C#

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.