Aracılığıyla paylaş


17 Dizi

17.1 Genel

Dizi, hesaplanan dizinler aracılığıyla erişilen bir dizi değişkeni içeren bir veri yapısıdır. Dizinin öğeleri olarak da adlandırılan bir dizideki değişkenlerin tümü aynı türdedir ve bu tür dizinin öğe türü olarak adlandırılır.

Bir dizi, her dizi öğesiyle ilişkili dizin sayısını belirleyen bir dereceye sahiptir. Bir dizinin sırası, dizinin boyutları olarak da adlandırılır. Bir derecesine sahip bir diziye tek boyutlu dizi adı verilir. Birden fazla dereceye sahip bir diziye çok boyutlu dizi adı verilir. Belirli boyutlu çok boyutlu diziler genellikle iki boyutlu diziler, üç boyutlu diziler vb. olarak adlandırılır. Bir dizinin her boyutu, sıfırdan büyük veya sıfıra eşit bir tam sayı olan ilişkili bir uzunluğa sahiptir. Boyut uzunlukları dizinin türünün bir parçası değildir, bunun yerine dizi türünün bir örneği çalışma zamanında oluşturulduğunda oluşturulur. Bir boyutun uzunluğu, bu boyut için geçerli dizin aralığını belirler: Uzunluk Nboyutu için, dizinler arasında 0 N – 1 kapsayıcı olabilir. Dizideki öğelerin toplam sayısı, dizideki her boyutun uzunluklarının çarpımını gösterir. Bir dizinin boyutlarından birinin veya daha fazlasının uzunluğu sıfırsa, dizinin boş olduğu söylenir.

Dizinin öğe türü bir dizi türü (§17.2.1) olabilir. Bu dizi dizileri çok boyutlu dizilerden farklıdır ve "pürüzlü dizileri" temsil etmek için kullanılabilir.

Örnek:

int[][] pascals = 
{
    new int[] {1},
    new int[] {1, 1},
    new int[] {1, 2, 1},
    new int[] {1, 3, 3, 1}
};

son örnek

Her dizi türü bir başvuru türüdür (§8.2). Bir dizinin öğe türü, değer türleri ve dizi türleri de dahil olmak üzere herhangi bir tür olabilir.

17.2 Dizi türleri

17.2.1 Genel

Dizi türleri için dil bilgisi üretimleri §8.2.1'de sağlanır.

Dizi türü bir non_array_type ve ardından bir veya daha fazla rank_specifierolarak yazılır.

non_array_type, kendisi array_type olmayan herhangi bir türdür.

Dizi türünün sırası, array_type en soldaki rank_specifier tarafından verilir: rank_specifier, dizinin bir derecesine ve rank_specifier "," belirteç sayısına sahip bir dizi olduğunu gösterir.

Bir dizi türünün öğe türü, en soldaki rank_specifier silinmesinden kaynaklanan türdür:

  • Formun T[R] dizi türü, rank R ve dizi olmayan öğe türüne Tsahip bir dizidir.
  • Formun T[R][R₁]...[Rₓ] dizi türü, rank R ve öğe türüne T[R₁]...[Rₓ]sahip bir dizidir.

Sonuç olarak, dizi olmayan son öğe türünden önce rank_specifiersoldan sağa okunur.

Örnek: içindeki T[][,,][,] türü, iki boyutlu dizilerinden oluşan üç boyutlu dizilerden oluşan tek boyutlu bir dizidir int. son örnek

Çalışma zamanında bir dizi türünün değeri veya bu dizi türünün bir örneğine başvuru olabilir null .

Not: §17.6 kurallarına uyarak, değer aynı zamanda bir kovaryant dizi türüne başvuru da olabilir. son not

17.2.2 System.Array türü

türü System.Array , tüm dizi türlerinin soyut temel türüdür. herhangi bir dizi türünden tarafından System.Arrayuygulanan herhangi bir arabirim türüne System.Array örtük başvuru dönüştürmesi (§10.2.8) vardır. ve tarafından System.Array uygulanan herhangi bir arabirim türünden System.Array herhangi bir dizi türüne açık bir başvuru dönüştürmesi (§10.3.5) vardır. System.Array kendisi bir array_type değildir. Bunun yerine, tüm array_type türetildiği bir class_type.

Çalışma zamanında, tür System.Array değeri olabilir veya herhangi bir dizi türünün örneğine başvuru olabilir null .

17.2.3 Diziler ve genel koleksiyon arabirimleri

Tek boyutlu bir dizi T[] arabirimini System.Collections.Generic.IList<T> (IList<T> kısaca) ve temel arabirimlerini uygular. Buna göre, ve temel arabirimlerinden T[] IList<T> örtük bir dönüştürme vardır. Buna ek olarak, 'den S sonraya S[] IList<T> örtük bir başvuru dönüştürmesi varsa ve ve temel arabirimlerinden örtük bir başvuru dönüştürmesi S[] IList<T> varsa (§10.2.8).T ile arasında açık bir başvuru dönüştürmesi S T varsa ve temel arabirimlerinden IList<T> S[] (§10.3.5) açık bir başvuru dönüştürmesi vardır.

Benzer şekilde, tek boyutlu bir dizi T[] de arabirimini System.Collections.Generic.IReadOnlyList<T> (IReadOnlyList<T> kısaca) ve temel arabirimlerini uygular. Buna göre, ve temel arabirimlerinden T[] IReadOnlyList<T> örtük bir dönüştürme vardır. Buna ek olarak, 'den S sonraya S[] IReadOnlyList<T> örtük bir başvuru dönüştürmesi varsa ve ve temel arabirimlerinden örtük bir başvuru dönüştürmesi S[] IReadOnlyList<T> varsa (§10.2.8).T ile arasında açık bir başvuru dönüştürmesi S T varsa ve temel arabirimlerinden IReadOnlyList<T> S[] (§10.3.5) açık bir başvuru dönüştürmesi vardır.

Örnek: Örneğin:

class Test
{
    static void Main()
    {
        string[] sa = new string[5];
        object[] oa1 = new object[5];
        object[] oa2 = sa;

        IList<string> lst1 = sa;  // Ok
        IList<string> lst2 = oa1; // Error, cast needed
        IList<object> lst3 = sa;  // Ok
        IList<object> lst4 = oa1; // Ok

        IList<string> lst5 = (IList<string>)oa1; // Exception
        IList<string> lst6 = (IList<string>)oa2; // Ok

        IReadOnlyList<string> lst7 = sa;        // Ok
        IReadOnlyList<string> lst8 = oa1;       // Error, cast needed
        IReadOnlyList<object> lst9 = sa;        // Ok
        IReadOnlyList<object> lst10 = oa1;      // Ok
        IReadOnlyList<string> lst11 = (IReadOnlyList<string>)oa1; // Exception
        IReadOnlyList<string> lst12 = (IReadOnlyList<string>)oa2; // Ok
    }
}

'den object[] IList<string> dönüştürme örtük değil, açık bir dönüştürme olduğundan atama lst2 = oa1 bir derleme zamanı hatası oluşturur. Atama (IList<string>)oa1 , bir değil, öğesine başvuracağından oa1 object[] string[]çalışma zamanında bir özel durum oluşturmasına neden olur. Ancak atama ( birIList<string>)oa2 öğesine başvuracağından oa2 string[]özel durum oluşturmasına neden olmaz.

son örnek

'den S[] IList<T>öğesine örtük veya açık bir başvuru dönüştürmesi olduğunda, 'den IList<T> ve temel arabirimlerinden S[] (§10.3.5) açık bir başvuru dönüştürmesi de vardır.

Bir dizi türü S[] uyguladığında IList<T>, uygulanan arabirimin bazı üyeleri özel durumlar oluşturabilir. Arabirimin uygulanmasının kesin davranışı bu belirtim kapsamının dışındadır.

17.3 Dizi oluşturma

Dizi örnekleri array_creation_expression tarafından (§12.8.16.5) veya array_initializer (§17.7) içeren alan veya yerel değişken bildirimleriyle oluşturulur. Dizi örnekleri, parametre dizisi (§15.6.2.4) içeren bağımsız değişken listesinin değerlendirilmesi kapsamında örtük olarak da oluşturulabilir.

Bir dizi örneği oluşturulduğunda, her boyutun derecesi ve uzunluğu oluşturulur ve ardından örneğin tüm ömrü boyunca sabit kalır. Başka bir deyişle, mevcut bir dizi örneğinin derecesini değiştirmek mümkün değildir ve boyutlarını yeniden boyutlandırmak mümkün değildir.

Dizi örneği her zaman bir dizi türündedir. Tür System.Array , örneği oluşturulamayan soyut bir türdür.

array_creation_expressiontarafından oluşturulan dizi öğeleri her zaman varsayılan değerlerine (§9.3) başlatılır.

17.4 Dizi öğesi erişimi

Dizi öğelerine, biçiminin element_access ifadeleri (§12.8.11.2) kullanılarak erişilir; burada A bir dizi türünün ifadesidir ve her Iₑ biri , , long, ulongveya türünde intuintbir ifadedir veya örtük olarak bu türlerden birine veya daha fazlasına dönüştürülebilirA[I₁, I₂, ..., Iₓ]. Dizi öğesi erişiminin sonucu, dizinler tarafından seçilen dizi öğesi olan bir değişkendir.

Bir dizinin öğeleri bir foreach deyim (§13.9.5) kullanılarak numaralandırılabilir.

17.5 Dizi üyeleri

Her dizi türü, türü tarafından System.Array bildirilen üyeleri devralır.

17.6 Dizi kovaryans

herhangi iki reference_typeA ve Biçin , 'den BA örtük bir başvuru dönüştürmesi (§10.2.8) veya açık başvuru dönüştürmesi (§10.3.5) varsa, dizi türünden dizi türüne A[R] B[R]aynı başvuru dönüştürmesi de vardır; burada R herhangi bir rank_specifier (her iki dizi türü için de aynıdır). Bu ilişki dizi kovaryans olarak bilinir. Dizi kovaryans, özellikle de dizi türündeki A[R] bir değerin , ile arasında örtük bir başvuru dönüştürmesi olması B koşuluyla, dizi türünün B[R]bir örneğine Abaşvuru olabileceği anlamına gelir.

Dizi kovaryans nedeniyle, başvuru türü dizilerinin öğelerine yapılan atamalar, dizi öğesine atanan değerin aslında izin verilen bir türe (§12.21.2) sahip olmasını sağlayan bir çalışma zamanı denetimi içerir.

Örnek:

class Test
{
    static void Fill(object[] array, int index, int count, object value) 
    {
        for (int i = index; i < index + count; i++)
        {
            array[i] = value;
        }
    }

    static void Main() 
    {
        string[] strings = new string[100];
        Fill(strings, 0, 100, "Undefined");
        Fill(strings, 0, 10, null);
        Fill(strings, 90, 10, 0);
    }
}

yöntemindeki ataması array[i] örtük olarak bir çalışma zamanı denetimi içerir. Bu denetim, öğesinin null value gerçek öğe türüyle arrayuyumlu bir türdeki nesneye başvuru veya başvuru olmasını Fill sağlar. içinde Mainilk iki çağrısı Fill başarılı olur, ancak üçüncü çağrı, ilk ataması yürütülürken bir'in System.ArrayTypeMismatchException atılması için array[i]neden olur. Özel durum, kutulanmış int bir dizide string depolanamadığından oluşur.

son örnek

Dizi kovaryans özellikle value_typedizilerine genişletilmez. Örneğin, bir int[] olarak değerlendirilmesine izin veren bir object[]dönüştürme yoktur.

17.7 Dizi başlatıcıları

Dizi başlatıcıları alan bildirimlerinde (§15.5), yerel değişken bildirimlerinde (§13.6.2) ve dizi oluşturma ifadelerinde (§12.8.16.5) belirtilebilir:

array_initializer
    : '{' variable_initializer_list? '}'
    | '{' variable_initializer_list ',' '}'
    ;

variable_initializer_list
    : variable_initializer (',' variable_initializer)*
    ;
    
variable_initializer
    : expression
    | array_initializer
    ;

Dizi başlatıcı, "" ve "" belirteçleri ile çevrelenmiş ve} "{," belirteçleriyle ayrılmış bir dizi değişken başlatıcıdan oluşur. Her değişken başlatıcı bir ifadedir veya çok boyutlu bir dizi söz konusu olduğunda iç içe dizi başlatıcıdır.

Dizi başlatıcının kullanıldığı bağlam, başlatılmakta olan dizinin türünü belirler. Dizi oluşturma ifadesinde, dizi türü başlatıcının hemen önüne geçer veya dizi başlatıcıdaki ifadelerden çıkarılır. Bir alan veya değişken bildiriminde, dizi türü bildirilen alanın veya değişkenin türüdür. Bir alan veya değişken bildiriminde dizi başlatıcı kullanıldığında,

int[] a = {0, 2, 4, 6, 8};

yalnızca eşdeğer dizi oluşturma ifadesi için kısaltmadır:

int[] a = new int[] {0, 2, 4, 6, 8};

Tek boyutlu bir dizi için, dizi başlatıcı, her biri dizinin öğe türüne örtük bir dönüştürmeye sahip olan bir dizi ifadeden (§10.2) oluşacaktır. İfadeler, sıfır dizinindeki öğesinden başlayarak dizi öğelerini artan sırada başlatır. Dizi başlatıcıdaki ifadelerin sayısı, oluşturulan dizi örneğinin uzunluğunu belirler.

Örnek: Yukarıdaki dizi başlatıcısı 5 uzunluğunda bir int[] örnek oluşturur ve ardından örneği aşağıdaki değerlerle başlatır:

a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8;

son örnek

Çok boyutlu bir dizi için, dizi başlatıcısı dizide boyut olduğu kadar iç içe yerleştirme düzeyine sahip olmalıdır. En dıştaki iç içe yerleştirme düzeyi en soldaki boyuta, en iç içe yerleştirme düzeyi ise en sağdaki boyuta karşılık gelir. Dizinin her boyutunun uzunluğu, dizi başlatıcıda karşılık gelen iç içe yerleştirme düzeyindeki öğelerin sayısına göre belirlenir. her iç içe dizi başlatıcısı için, öğe sayısı aynı düzeydeki diğer dizi başlatıcıları ile aynı olmalıdır.

Örnek: Örnek:

int[,] b = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};

en soldaki boyut için beş, en sağdaki boyut için iki uzunluklu iki boyutlu bir dizi oluşturur:

int[,] b = new int[5, 2];

ve ardından dizi örneğini aşağıdaki değerlerle başlatır:

b[0, 0] = 0; b[0, 1] = 1;
b[1, 0] = 2; b[1, 1] = 3;
b[2, 0] = 4; b[2, 1] = 5;
b[3, 0] = 6; b[3, 1] = 7;
b[4, 0] = 8; b[4, 1] = 9;

son örnek

En sağdakinden başka bir boyuta uzunluk sıfır ile verilirse, sonraki boyutların da uzunluğu sıfır olduğu varsayılır.

Örnek:

int[,] c = {};

hem en soldaki hem de en sağdaki boyut için uzunluğu sıfır olan iki boyutlu bir dizi oluşturur:

int[,] c = new int[0, 0];

son örnek

Dizi oluşturma ifadesi hem açık boyut uzunluklarını hem de dizi başlatıcıyı içerdiğinde uzunluklar sabit ifadeler olmalı ve her iç içe yerleştirme düzeyindeki öğelerin sayısı ilgili boyut uzunluğuyla eşleşmelidir.

Örnek: Aşağıda bazı örnekler verilmiştir:

int i = 3;
int[] x = new int[3] {0, 1, 2}; // OK
int[] y = new int[i] {0, 1, 2}; // Error, i not a constant
int[] z = new int[3] {0, 1, 2, 3}; // Error, length/initializer mismatch

Burada, boyut uzunluğu ifadesi sabit olmadığından başlatıcı y derleme zamanı hatasıyla sonuçlanır ve başlatıcıdaki z uzunluk ve öğe sayısı kabul edilmediğinden başlatıcı derleme zamanı hatasıyla sonuçlanır.

son örnek

Not: C# bir array_initializer sonunda sondaki virgüle izin verir. Bu söz dizimi, bu tür bir listeden üye ekleme veya silme esnekliği sağlar ve bu listelerin makine oluşturulmasını kolaylaştırır. son not