Dizin oluşturucuları kullanma (C# Programlama Kılavuzu)

Dizin oluşturucular, istemci uygulamalarının dizi olarak erişebileceği bir sınıf, yapı veya arabirim oluşturmanıza olanak tanıyan söz dizileridir. Derleyici bir Item özellik (veya varsa alternatif olarak adlandırılmış bir özellik IndexerNameAttribute ) ve uygun erişimci yöntemlerini oluşturur. Dizin oluşturucular en sık, birincil amacı bir iç koleksiyonu veya diziyi kapsüllemek olan türlerde uygulanır. Örneğin, 24 saatlik bir süre boyunca 10 farklı zamanda kaydedildiği gibi Fahrenheit'teki sıcaklığı temsil eden bir sınıfınız TempRecord olduğunu varsayalım. sınıfı, sıcaklık değerlerini depolamak için bir temps tür float[] dizisi içerir. İstemciler, bu sınıfta bir dizin oluşturucu uygulayarak bir örnekteki sıcaklıklara TempRecord olarak float temp = tempRecord.temps[4]değil olarak float temp = tempRecord[4] erişebilir. Dizin oluşturucu gösterimi yalnızca istemci uygulamaları için söz dizimini basitleştirmez; ayrıca sınıfını ve amacını diğer geliştiricilerin anlaması için daha sezgisel hale getirir.

Bir sınıf veya yapıda dizin oluşturucu bildirmek için aşağıdaki örnekte gösterildiği gibi bu anahtar sözcüğü kullanın:

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

Önemli

Dizin oluşturucu bildirilmesi, nesnesinde adlı Item bir özelliği otomatik olarak oluşturur. Özelliğine Item örnek üye erişim ifadesinden doğrudan erişilemez. Ayrıca, dizin oluşturuculu bir nesneye kendi Item özelliğinizi eklerseniz CS0102 derleyici hatası alırsınız. Bu hatayı önlemek için, bu makalenin IndexerNameAttribute devamında açıklandığı gibi dizin oluşturucuyu yeniden adlandırın.

Açıklamalar

Dizin oluşturucunun türü ve parametrelerinin türü en az dizin oluşturucunun kendisi kadar erişilebilir olmalıdır. Erişilebilirlik düzeyleri hakkında daha fazla bilgi için bkz . Erişim Değiştiricileri.

Dizin oluşturucuları bir arabirimle kullanma hakkında daha fazla bilgi için bkz . Arabirim Dizin Oluşturucuları.

Dizin oluşturucunun imzası, resmi parametrelerinin sayısından ve türlerinden oluşur. Dizin oluşturucu türünü veya resmi parametrelerin adlarını içermez. Aynı sınıfta birden fazla dizin oluşturucu bildirirseniz, bunların farklı imzaları olmalıdır.

Dizin oluşturucu değişken olarak sınıflandırılmamıştır; bu nedenle, bir dizin oluşturucu değeri bir başvuru olmadığı sürece (veya out parametresi olarakref) başvuruyla geçirilemiyor (yani, başvuruyla döndürülüyor).)

Dizin oluşturucuya diğer dillerin kullanabileceği bir ad sağlamak için, aşağıdaki örnekte gösterildiği gibi kullanın System.Runtime.CompilerServices.IndexerNameAttribute:

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

Bu dizin oluşturucu, dizin oluşturucu adı TheItemözniteliği tarafından geçersiz kılındığı için adına sahiptir. Dizin oluşturucu adı varsayılan olarak şeklindedir Item.

Örnek 1

Aşağıdaki örnekte, özel dizi alanı, tempsve dizin oluşturucu bildirme gösterilmektedir. Dizin oluşturucu, örneğine tempRecord[i]doğrudan erişimi etkinleştirir. Dizin oluşturucuyu kullanmanın alternatifi, diziyi genel üye olarak bildirmek ve üyelerine tempRecord.temps[i]doğrudan erişmektir.

public class TempRecord
{
    // Array of temperature values
    float[] temps =
    [
        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şimi değerlendirildiğinde, örneğin bir Console.Write deyimde get erişimcisinin çağrıldığına dikkat edin. Bu nedenle, erişimci yoksa get derleme zamanı hatası oluşur.

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]}");
}

Diğer değerleri kullanarak dizin oluşturma

C# dizin oluşturucu parametre türünü tamsayı ile sınırlamaz. Örneğin, dizin oluşturucu ile bir dize kullanmak yararlı olabilir. Böyle bir dizin oluşturucu, koleksiyondaki dize aranarak ve uygun değer döndürülerek uygulanabilir. Erişimciler aşırı yüklenebildiği için, dize ve tamsayı sürümleri birlikte bulunabilir.

Örnek 2

Aşağıdaki örnek, haftanın günlerini depolayan bir sınıf bildirir. Erişimci get bir dize alır, bir günün adını alır ve karşılık gelen tamsayıyı döndürür. Örneğin, "Pazar" 0 döndürür, "Pazartesi" 1 döndürür ve bu şekilde devam eder.

// 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");
    }
}

Kullanım örneği 2

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}");
}

Örnek 3

Aşağıdaki örnek, sabit listesi kullanarak System.DayOfWeek haftanın günlerini depolayan bir sınıf bildirir. Erişimci get , bir DayOfWeekgünün değerini alır ve karşılık gelen tamsayıyı döndürür. Örneğin, DayOfWeek.Sunday 0 döndürür, DayOfWeek.Monday 1 döndürür, vb.

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.");
    }
}

Kullanım örneği 3

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}");
}

Sağlam programlama

Dizin oluşturucuların güvenliğini ve güvenilirliğini geliştirmenin iki ana yolu vardır:

  • İ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. Bu makalenin önceki bölümlerindeki ilk örnekte TempRecord sınıfı, istemci kodunun girişi dizin oluşturucuya geçirmeden önce doğrulamasını sağlayan bir Length özelliği sağlar. Hata işleme kodunu dizin oluşturucunun içine de yerleştirebilirsiniz. Dizin oluşturucu erişimcisinde oluşturduğunuz özel durumları kullanıcılar için belgelediğinizden emin olun.

  • Get ve erişimcilerinin erişilebilirliğini makul olduğu kadar kısıtlayıcı olacak şekilde ayarlayın. Bu özellikle aksesuar için set önemlidir. Daha fazla bilgi için bkz . Erişimci Erişilebilirliğini Kısıtlama.

Ayrıca bkz.