Dizin oluşturucular kullanma (C# Programlama Kılavuzu)Using indexers (C# Programming Guide)

Dizin oluşturucular, istemci uygulamaların dizi olarak erişebileceği bir sınıf, Yapıveya arabirim oluşturmanıza imkan tanıyan sözdizimsel bir kolaylığıdır.Indexers are a syntactic convenience that enable you to create a class, struct, or interface that client applications can access as an array. Derleyici bir Item Özellik (veya varsa alternatif olarak adlandırılmış bir özellik) oluşturur IndexerNameAttribute ve uygun erişimci yöntemleri olur.The compiler will generate an Item property (or an alternatively named property if IndexerNameAttribute is present), and the appropriate accessor methods. Dizin oluşturucular en sık, birincil amacı bir iç koleksiyonu veya diziyi kapsüllemek olan türlerde uygulanır.Indexers are most frequently implemented in types whose primary purpose is to encapsulate an internal collection or array. Örneğin, TempRecord 24 saatlik bir dönemde 10 farklı zamanda kaydedildiği gibi Fahrenhayt 'teki sıcaklığı temsil eden bir sınıfınız olduğunu varsayalım.For example, suppose you have a class TempRecord that represents the temperature in Fahrenheit as recorded at 10 different times during a 24-hour period. Sınıfı, temps float[] sıcaklık değerlerini depolamak için türünde bir dizi içerir.The class contains a temps array of type float[] to store the temperature values. Bu sınıfta bir Dizin Oluşturucu uygulayarak istemciler, gibi bir örnekteki sıcakya farklı şekilde erişebilir TempRecord float temp = tempRecord[4] float temp = tempRecord.temps[4] .By implementing an indexer in this class, clients can access the temperatures in a TempRecord instance as float temp = tempRecord[4] instead of as float temp = tempRecord.temps[4]. Dizin Oluşturucu gösterimi yalnızca istemci uygulamaları için söz dizimini basitleştirir; Ayrıca, diğer geliştiricilerin anlayabilmesi için sınıfı ve amacını daha sezgisel hale getirir.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.

Bir sınıf veya yapı biriminde bir Dizin Oluşturucu bildirmek için aşağıdaki örnekte gösterildiği gibi this anahtar sözcüğünü kullanın:To declare an indexer on a class or struct, use the this keyword, as the following example shows:

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

Önemli

Bir dizin oluşturucunun bildirilmesi, otomatik olarak nesne üzerinde adlı bir özellik oluşturur Item .Declaring an indexer will automatically generate a property named Item on the object. ItemÖzelliğe, örnek üye erişim ifadesindendoğrudan erişilemez.The Item property is not directly accessible from the instance member access expression. Ayrıca, kendi Item özelliklerinizi bir dizin oluşturucuya sahip bir nesneye eklerseniz, bir CS0102 derleyici hatasıalırsınız.Additionally, if you add your own Item property to an object with an indexer, you'll get a CS0102 compiler error. Bu hatayı önlemek için, IndexerNameAttribute Dizin oluşturucuyu aşağıda açıklandığı gibi yeniden adlandır ' ı kullanın.To avoid this error, use the IndexerNameAttribute rename the indexer as detailed below.

AçıklamalarRemarks

Bir dizin oluşturucunun türü ve parametrelerinin türü en az dizin oluşturucunun kendisi olarak erişilebilir olmalıdır.The type of an indexer and the type of its parameters must be at least as accessible as the indexer itself. Erişilebilirlik düzeyleri hakkında daha fazla bilgi için bkz. erişim değiştiricileri.For more information about accessibility levels, see Access Modifiers.

Arabirim ile Dizin oluşturucular kullanma hakkında daha fazla bilgi için bkz. arabirim dizin oluşturucular.For more information about how to use indexers with an interface, see Interface Indexers.

Bir dizin oluşturucunun imzası, biçimsel parametrelerinin sayısı ve türlerinden oluşur.The signature of an indexer consists of the number and types of its formal parameters. Dizin Oluşturucu türü veya biçimsel parametrelerin adlarını içermez.It doesn't include the indexer type or the names of the formal parameters. Aynı sınıfta birden fazla Dizin Oluşturucu bildirirseniz, bunların farklı imzaları olmalıdır.If you declare more than one indexer in the same class, they must have different signatures.

Dizin Oluşturucu değeri bir değişken olarak sınıflandırılmıyor; Bu nedenle, Dizin Oluşturucu değeri bir ref veya Out parametresi olarak geçirilemez.An indexer value is not classified as a variable; therefore, you cannot pass an indexer value as a ref or out parameter.

Dizin oluşturucuyu diğer dillerin kullanabileceği bir adla sağlamak için, System.Runtime.CompilerServices.IndexerNameAttribute Aşağıdaki örnekte gösterildiği gibi kullanın:To provide the indexer with a name that other languages can use, use System.Runtime.CompilerServices.IndexerNameAttribute, as the following example shows:

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

Dizin TheItem Oluşturucu adı özniteliği tarafından geçersiz kılındığından, bu dizin oluşturucunun adı olacaktır.This indexer will have the name TheItem, as it is overridden by the indexer name attribute. Varsayılan olarak, dizin oluşturucu adı Item .By default, the indexer name is Item.

Örnek 1Example 1

Aşağıdaki örnek, bir özel dizi alanının, temps ve bir dizin oluşturucunun nasıl bildirilemeyeceğini gösterir.The following example shows how to declare a private array field, temps, and an indexer. Dizin Oluşturucu örneğe doğrudan erişim sağlar tempRecord[i] .The indexer enables direct access to the instance tempRecord[i]. Dizin oluşturucuyu kullanmanın alternatifi, diziyi ortak bir üye olarak bildirmeli ve üyelerine doğrudan erişim sağlar tempRecord.temps[i] .The alternative to using the indexer is to declare the array as a public member and access its members, tempRecord.temps[i], directly.

public class TempRecord
{
    // Array of temperature values
    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 => temps.Length;
    
    // Indexer declaration.
    // If index is out of range, the temps array will throw the exception.
    public float this[int index]
    {
        get => temps[index];
        set => temps[index] = value;
    }
}

Bir dizin oluşturucunun erişim değerlendirildiği zaman, örneğin bir Console.Write ifadede, Get erişimcisinin çağrıldığına dikkat edin.Notice that when an indexer's access is evaluated, for example, in a Console.Write statement, the get accessor is invoked. Bu nedenle, get bir erişimci yoksa, bir derleme zamanı hatası oluşur.Therefore, if no get accessor exists, a compile-time error occurs.

using System;

class Program
{
    static void Main()
    {
        var 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++)
        {
            Console.WriteLine($"Element #{i} = {tempRecord[i]}");
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        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
    */
}

Diğer değerleri kullanarak dizin oluşturmaIndexing using other values

C#, dizin oluşturucu parametre türünü tamsayı olarak sınırlamaz.C# doesn't limit the indexer parameter type to integer. Örneğin, bir Dizin Oluşturucu ile dize kullanmak yararlı olabilir.For example, it may be useful to use a string with an indexer. Bu tür bir Dizin Oluşturucu koleksiyondaki dizeyi arayarak ve uygun değeri döndürerek uygulanabilir.Such an indexer might be implemented by searching for the string in the collection, and returning the appropriate value. Erişimciler aşırı yüklenmiş olabilir, dize ve tamsayı sürümleri birlikte kullanılabilir.As accessors can be overloaded, the string and integer versions can coexist.

Örnek 2Example 2

Aşağıdaki örnek, haftanın günlerini depolayan bir sınıf bildirir.The following example declares a class that stores the days of the week. getErişimci bir dize, bir günün adı alır ve karşılık gelen tamsayıyı döndürür.A get accessor takes a string, the name of a day, and returns the corresponding integer. Örneğin, "Pazar" 0, "Pazartesi" 1 döndürür ve bu şekilde devam eder.For example, "Sunday" returns 0, "Monday" returns 1, and so on.

using System;

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

    // Indexer with only a get accessor with the expression-bodied definition:
    public int this[string day] => FindDayIndex(day);

    private int FindDayIndex(string day)
    {
        for (int j = 0; j < days.Length; j++)
        {
            if (days[j] == day)
            {
                return j;
            }
        }

        throw new ArgumentOutOfRangeException(
            nameof(day),
            $"Day {day} is not supported.\nDay input must be in the form \"Sun\", \"Mon\", etc");
    }
}

Tüketim örneği 2Consuming example 2

using System;

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

        try
        {
            Console.WriteLine(week["Made-up day"]);
        }
        catch (ArgumentOutOfRangeException e)
        {
            Console.WriteLine($"Not supported input: {e.Message}");
        }
    }
    // Output:
    // 5
    // Not supported input: Day Made-up day is not supported.
    // Day input must be in the form "Sun", "Mon", etc (Parameter 'day')
}

Örnek 3Example 3

Aşağıdaki örnek, sabit listesini kullanarak haftanın günlerini depolayan bir sınıf bildirir System.DayOfWeek .The following example declares a class that stores the days of the week using the System.DayOfWeek enum. getErişimci bir DayOfWeek günün değerini alır ve karşılık gelen tamsayıyı döndürür.A get accessor takes a DayOfWeek, the value of a day, and returns the corresponding integer. Örneğin, DayOfWeek.Sunday 0 döndürür, DayOfWeek.Monday 1 döndürür ve bu şekilde devam eder.For example, DayOfWeek.Sunday returns 0, DayOfWeek.Monday returns 1, and so on.

using System;
using Day = System.DayOfWeek;

class DayOfWeekCollection
{
    Day[] days =
    {
        Day.Sunday, Day.Monday, Day.Tuesday, Day.Wednesday,
        Day.Thursday, Day.Friday, Day.Saturday
    };

    // Indexer with only a get accessor with the expression-bodied definition:
    public int this[Day day] => FindDayIndex(day);

    private int FindDayIndex(Day day)
    {
        for (int j = 0; j < days.Length; j++)
        {
            if (days[j] == day)
            {
                return j;
            }
        }
        throw new ArgumentOutOfRangeException(
            nameof(day),
            $"Day {day} is not supported.\nDay input must be a defined System.DayOfWeek value.");
    }
}

Örnek 3Consuming example 3

using System;

class Program
{
    static void Main()
    {
        var week = new DayOfWeekCollection();
        Console.WriteLine(week[DayOfWeek.Friday]);

        try
        {
            Console.WriteLine(week[(DayOfWeek)43]);
        }
        catch (ArgumentOutOfRangeException e)
        {
            Console.WriteLine($"Not supported input: {e.Message}");
        }
    }
    // Output:
    // 5
    // Not supported input: Day 43 is not supported.
    // Day input must be a defined System.DayOfWeek value. (Parameter 'day')
}

Güçlü programlamaRobust programming

Dizin oluşturucularının güvenliğinin ve güvenilirliğinin iyileşmesi için kullanabileceğiniz iki ana yol vardır:There are two main ways in which the security and reliability of indexers can be improved:

  • İstemci kodunun geçersiz bir dizin değeri geçirme olasılığını işlemek için bir tür hata işleme stratejisi eklediğinizden emin olun.Be sure to incorporate some type of error-handling strategy to handle the chance of client code passing in an invalid index value. Bu konunun önceki kısımlarında yer alan ilk örnekte, TempRecord sınıfı, istemci kodun dizin oluşturucuya geçirmeden önce girişi doğrulamasını sağlayan bir length özelliği sağlar.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. Hata işleme kodunu dizin oluşturucunun içine de yerleştirebilirsiniz.You can also put the error handling code inside the indexer itself. Bir Dizin Oluşturucu erişimcisinde oluşturduğunuz tüm özel durumları kullanıcılara belgelediğinizden emin olun.Be sure to document for users any exceptions that you throw inside an indexer accessor.

  • Get ve set erişimcilerinin erişilebilirliğini makul olacak şekilde kısıtlayıcı olarak belirleyin.Set the accessibility of the get and set accessors to be as restrictive as is reasonable. Bu, set özellikle erişimcinin açısından önemlidir.This is important for the set accessor in particular. Daha fazla bilgi için bkz. erişimci erişilebilirliğini kısıtlama.For more information, see Restricting Accessor Accessibility.

Ayrıca bkz.See also