Verwenden von Indexern (C#-Programmierhandbuch)Using Indexers (C# Programming Guide)

Indexer sind ein syntaktisches Hilfsmittel, um Ihnen die Erstellung einer Klasse, einer Struktur, oder einer Schnittstelle zu ermöglichen, auf die Clientanwendungen wie auf ein Array zugreifen können.Indexers are a syntactic convenience that enable you to create a class, struct, or interface that client applications can access just as an array. Indexer werden am häufigsten in Typen implementiert, deren Hauptzweck darin besteht, eine interne Auflistung oder ein Array zu kapseln.Indexers are most frequently implemented in types whose primary purpose is to encapsulate an internal collection or array. Angenommen Sie verfügen über eine Klasse mit dem Namen .TempRecord, zur Darstellung der Temperatur in Fahrenheit zu 10 verschiedenen Zeitpunkten während eines 24-stündigen Zeitraums.For example, suppose you have a class named TempRecord that represents the temperature in Farenheit as recorded at 10 different times during a 24 hour period. Die Klasse enthält ein Array mit dem Namen "Temps" vom "float"-Datentyp, um die Temperaturen darzustellen, und einen DateTime, der das Datum darstellt, an welchem die Temperaturen erfasst wurden.The class contains an array named "temps" of type float to represent the temperatures, and a DateTime that represents the date the temperatures were recorded. Durch die Implementierung eines Indexers in dieser Klasse, können Clients auf die Temperaturen in einer TempRecord-Instanz als float temp = tr[4] zugreifen, statt als float temp = tr.temps[4].By implementing an indexer in this class, clients can access the temperatures in a TempRecord instance as float temp = tr[4] instead of as float temp = tr.temps[4]. Die Angabe des Indexers vereinfacht nicht nur die Syntax für Clientanwendungen; die Klasse und Ihr Zweck können außerdem intuitiver von anderen Entwicklern verstanden werden.The indexer notation not only simplifies the syntax for client applications; it also makes the class and its purpose more intuitive for other developers to understand.

Um einen Indexer auf eine Klasse oder Struktur zu deklarieren, verwenden Sie das this -Schlüsselwort, wie im folgenden Beispiel:To declare an indexer on a class or struct, use the this keyword, as in this example:

public int this[int index]    // Indexer declaration  
{  
    // get and set accessors  
}  

HinweiseRemarks

Der Typ eines Indexers und der Typ seiner Parameter müssen zumindest dieselben Zugriffsmöglichkeiten bieten wie der Indexer selbst.The type of an indexer and the type of its parameters must be at least as accessible as the indexer itself. Weitere Informationen zu den Zugriffsebenen finden Sie unter Zugriffsmodifizierer.For more information about accessibility levels, see Access Modifiers.

Weitere Informationen zum Verwenden von Indexern mit einer Schnittstelle finden Sie unter Schnittstellenindexer.For more information about how to use indexers with an interface, see Interface Indexers.

Die Signatur eines Indexers besteht aus der Anzahl und den Typen seiner formalen Parameter.The signature of an indexer consists of the number and types of its formal parameters. Sie umfasst nicht den Indexertyp oder die Namen der formalen Parameter.It does not include the indexer type or the names of the formal parameters. Wenn Sie mehrere Indexer in derselben Klasse deklarieren, müssen sie verschiedene Signaturen aufweisen.If you declare more than one indexer in the same class, they must have different signatures.

Ein Indexerwert wird nicht als Variable klassifiziert. Aus diesem Grund können Sie keinen Indexerwert als Ref- oder out-Parameter übergeben.An indexer value is not classified as a variable; therefore, you cannot pass an indexer value as a ref or out parameter.

Um dem Indexer einen Namen zu geben, den andere Sprachen verwenden können, verwenden Sie ein name-Attribut in der Deklaration.To provide the indexer with a name that other languages can use, use a name attribute in the declaration. Zum Beispiel:For example:

[System.Runtime.CompilerServices.IndexerName("TheItem")]  
public int this [int index]   // Indexer declaration  
{  
}  

Dieser Indexer hat den Namen TheItem.This indexer will have the name TheItem. Wird kein Namensattribut bereitgestellt, wird Item zum Standardnamen.Not providing the name attribute would make Item the default name.

Beispiel 1Example 1

BeschreibungDescription

Im folgenden Beispiel wird die Deklaration eines öffentlichen Arrayfelds, temps, und eines Indexers dargestellt.The following example shows how to declare a private array field, temps, and an indexer. Der Indexer ermöglicht den direkten Zugriff auf die Instanz tempRecord[i].The indexer enables direct access to the instance tempRecord[i]. Als Alternative zur Verwendung des Indexers, kann das Array als öffentliches Mitglied deklariert und direkt auf dessen Mitglieder, tempRecord.temps[i], zugegriffen werden.The alternative to using the indexer is to declare the array as a public member and access its members, tempRecord.temps[i], directly.

Beachten Sie, dass, wenn der Zugriff eines Indexers, z.B. in einer Console.Write-Anweisung ausgewertet wird, der get-Accessor aufgerufen wird.Notice that when an indexer's access is evaluated, for example, in a Console.Write statement, the get accessor is invoked. Wenn kein get-Accessor vorhanden ist, tritt deshalb ein Kompilierzeitfehler auf.Therefore, if no get accessor exists, a compile-time error occurs.

CodeCode

class TempRecord
{
    // Array of temperature values
    private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F, 
                                            61.3F, 65.9F, 62.1F, 59.2F, 57.5F };

    // To enable client code to validate input 
    // when accessing your indexer.
    public int Length
    {
        get { return temps.Length; }
    }
    // Indexer declaration.
    // If index is out of range, the temps array will throw the exception.
    public float this[int index]
    {
        get
        {
            return temps[index];
        }

        set
        {
            temps[index] = value;
        }
    }
}

class MainClass
{
    static void Main()
    {
        TempRecord tempRecord = new TempRecord();
        // Use the indexer's set accessor
        tempRecord[3] = 58.3F;
        tempRecord[5] = 60.1F;

        // Use the indexer's get accessor
        for (int i = 0; i < 10; i++)
        {
            System.Console.WriteLine("Element #{0} = {1}", i, tempRecord[i]);
        }

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();

    }
}
/* Output:
        Element #0 = 56.2
        Element #1 = 56.7
        Element #2 = 56.5
        Element #3 = 58.3
        Element #4 = 58.8
        Element #5 = 60.1
        Element #6 = 65.9
        Element #7 = 62.1
        Element #8 = 59.2
        Element #9 = 57.5
    */

Indizieren mit anderen WertenIndexing Using Other Values

C# beschränkt den Typ des Indexes nicht auf Integer.C# does not limit the index type to integer. Beispielsweise kann es sinnvoll sein, eine Zeichenfolge mit einem Indexer zu verwenden.For example, it may be useful to use a string with an indexer. Ein solcher Indexer kann implementiert werden, indem die Zeichenfolge in der Auflistung gesucht und der richtige Wert zurückgegeben wird.Such an indexer might be implemented by searching for the string in the collection, and returning the appropriate value. Da Accessoren überladen werden können, können die Zeichenfolge- und die Integer-Version zusammen verwendet werden.As accessors can be overloaded, the string and integer versions can co-exist.

Beispiel 2Example 2

BeschreibungDescription

In diesem Beispiel wird eine Klasse deklariert, die die Wochentage speichert.In this example, a class is declared that stores the days of the week. Ein get-Accessor wird deklariert, der eine Zeichenfolge und den Namen eines Tages annimmt, und den entsprechenden Integer zurückgibt.A get accessor is declared that takes a string, the name of a day, and returns the corresponding integer. Z.B. gibt Sonntag 0 zurück, Montag gibt 1 zurück, usw.For example, Sunday will return 0, Monday will return 1, and so on.

CodeCode

// Using a string as an indexer value
class DayCollection
{
    string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };

    // This method finds the day or returns -1
    private int GetDay(string testDay)
    {

        for (int j = 0; j < days.Length; j++)
        {
            if (days[j] == testDay)
            {
                return j;
            }
        }

        throw new System.ArgumentOutOfRangeException(testDay, "testDay must be in the form \"Sun\", \"Mon\", etc");
    }

    // The get accessor returns an integer for a given string
    public int this[string day]
    {
        get
        {
            return (GetDay(day));
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        DayCollection week = new DayCollection();
        System.Console.WriteLine(week["Fri"]);

        // Raises ArgumentOutOfRangeException
        System.Console.WriteLine(week["Made-up Day"]);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
// Output: 5

Stabile ProgrammierungRobust Programming

Es gibt zwei grundlegende Möglichkeiten, mit denen die Sicherheit und die Zuverlässigkeit von Indexern verbessert werden kann:There are two main ways in which the security and reliability of indexers can be improved:

  • Integrieren Sie irgendeine Form von Fehlerbehandlungsstrategie, für den Fall, dass Clientcode in einem ungültigen Indexwert übergeben wird.Be sure to incorporate some type of error-handling strategy to handle the chance of client code passing in an invalid index value. Im ersten Beispiel weiter oben in diesem Thema stellt die TempRecord-Klasse eine Length-Eigenschaft bereit, die dem Clientcode ermöglicht, die Eingabe vor der Übergabe an den Indexer zu überprüfen.In the first example earlier in this topic, the TempRecord class provides a Length property that enables the client code to verify the input before passing it to the indexer. Sie können den Fehlerbehandlungscode auch in den Indexer selbst einfügen.You can also put the error handling code inside the indexer itself. Achten Sie darauf alle Ausnahmen, die Sie innerhalb eines Indexeraccessors auslösen, für Benutzer zu dokumentieren.Be sure to document for users any exceptions that you throw inside an indexer accessor.

  • Schränken Sie den Zugriff auf den get- und set-Accessor so ein, dass die Beschränkung angemessen ist.Set the accessibility of the get and set accessors to be as restrictive as is reasonable. Dies ist insbesondere wichtig für den set-Accessor.This is important for the set accessor in particular. Weitere Informationen finden Sie unter Einschränken des Accessorzugriffs.For more information, see Restricting Accessor Accessibility.

Siehe auchSee Also

C#-ProgrammierhandbuchC# Programming Guide
IndexerIndexers
EigenschaftenProperties