Używanie indeksatorów (Przewodnik programowania w języku C#)

Indeksatory są syntaktyczne wygodę, które umożliwiają tworzenie klasy, struct, lub interfejsu że aplikacje klienckie mogą uzyskać dostęp tylko jako tablicę.Indeksatory najczęściej są implementowane w typów, których głównym celem jest hermetyzowania wewnętrznej kolekcji lub w tablicy.Na przykład załóżmy, że istnieje klasa o nazwie TempRecord, reprezentującą temperatury w Farenheit zarejestrowana 10 różnych porach w okresie 24-godzinnym.Klasa zawiera tablicy o nazwie "temps" pływaka typu do reprezentacji temperatury oraz DateTime reprezentującym datę temperatur zostały zarejestrowane.Implementując indeksowanie w tej klasie, klienci mogą uzyskać dostęp temperatury w instancji TempRecord jako float temp = tr[4] zamiast jako float temp = tr.temps[4].Notacja indeksatora nie tylko upraszcza składnia dla aplikacji klienckich; Powoduje to również klasy i jej cel bardziej intuicyjny dla innych programistów do zrozumienia.

Aby zadeklarować indeksowanie na klasy lub struktury, użyj to słowa kluczowego, jak w poniższym przykładzie:

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

Uwagi

Typ indeksowania i typ jej parametry muszą być co najmniej dostępne jako indeksatora, sam.Aby uzyskać więcej informacji na temat poziomów ułatwień dostępu Zobacz Modyfikatorów dostępu.

Aby uzyskać więcej informacji na temat używania indeksatory z interfejsem zobacz Indeksatory interfejsu.

Podpis indeksatorze składa się z liczby i typów jego parametrów formalnych.Nie obejmuje indeksatora typu lub nazwy parametrów formalnych.Przy deklarowaniu więcej niż jeden indeksator w tej samej klasie, muszą mieć różne podpisy.

Wartość indeksatora nie jest sklasyfikowana jako zmienna; w związku z tym, nie można przekazać wartości indeksatora jako ref lub z parametru.

Aby dostarczyć indeksatora z nazwą, która może być używana w innych językach, należy użyć name atrybutu w zgłoszeniu.Na przykład:

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

Indeksator ten będzie miał nazwę TheItem.Nie świadczy atrybut name spowodowałoby, że Item nazwę domyślną.

Przykład 1

Opis

Poniższy przykład ilustruje sposób deklarowania pola tablicy prywatne, tempsi indeksowanie.Indeksowanie umożliwia bezpośredni dostęp do wystąpienia tempRecord[i].Alternatywą do użycia indeksatora jest deklarować tablic jako publicznych Członkowskich i uzyskać dostęp do swoich członków, tempRecord.temps[i], bezpośrednio.

Warto zauważyć, że podczas indeksowania dostępu jest oceniane, na przykład w Console.Write instrukcji, uzyskać akcesor jest wywoływany.W związku z tym jeśli nie get istnieje akcesor, wystąpi błąd kompilacji.

Kod

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
    */

Indeksowanie za pomocą innych wartości

C# nie ogranicza typ indeksu do liczby całkowitej.Na przykład może być przydatne użycie ciąg w indeksatorze.Indeksowanie takie może być realizowane przez wyszukiwanie ciągu w kolekcji i zwrócenie odpowiedniej wartości.Jak mogą być przeciążone akcesory, ciąg i całkowitą wersje mogą współistnieć.

Przykład 2

Opis

W tym przykładzie klasy jest zadeklarowane przechowujący dni tygodnia.A get akcesor jest zadeklarowany jako ciąg znaków, nazwę dnia tygodnia i zwraca odpowiednie liczby całkowitej.Na przykład niedziela będzie zwraca wartość 0, poniedziałek zostanie zwrócona wartość 1 itd.

Kod

// 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

Stabilne Programowanie

Istnieją dwa główne sposoby, w których może być ulepszony zabezpieczeń i niezawodności indeksatory:

  • Należy upewnić się, że włączenie niektórych typu strategii obsługi błędów do obsługi szansę przekazując wartość indeksu nieprawidłowy kod klienta.W pierwszym przykładzie we wcześniejszej części tego tematu klasa TempRecord udostępnia właściwość długości, która umożliwia kod klienta przed przekazaniem go do indeksatora wejociowy.Można również umieścić kod wewnątrz samego indeksatora obsługi błędów.Należy upewnić się, że dokument dla użytkowników wyjątkami, które throw wewnątrz akcesor operacji indeksowania.

  • Ustawianie dostępności get i set akcesorów być tak restrykcyjne, ponieważ jest uzasadnione.Jest to istotne dla set akcesor, w szczególności.Aby uzyskać więcej informacji, zobacz Ograniczanie dostępności metody dostępu (Przewodnik programowania w języku C#).

Zobacz też

Informacje

Indeksatory (Przewodnik programowania w języku C#)

Właściwości (Przewodnik programowania w języku C#)

Koncepcje

Przewodnik programowania w języku C#