Aracılığıyla paylaş


18 Genişletilmiş dizin oluşturma ve dilimleme

18.1 Genel

Bu yan tümce, yerleşik olarak genişletilmiş dizinlenebilir ve dilimlenebilirkoleksiyon türleri için bir model sağlar:

  • Bu yan tümcede System.Index (§18.2) ve System.Range (§18.3) tanıtılan türler;
  • Önceden tanımlanmış birli ^ (§12.9.6) ve ikili .. (§12.10) işleçleri; ve
  • element_access ifadesi.

Modelin altında bir tür şu şekilde sınıflandırılır:

  • bir öğegrubunu temsil eden bir koleksiyon
  • değere veya başvuruya göre türün tek bir öğesini döndüren ve/veya ayarlayan tek bir bağımsız değişken ifadesi olan bir element_access ifadesini destekliyorsa Index koleksiyon; ve
  • türündeki öğelerin bir dilimini değere göre döndüren tek bir bağımsız değişken ifadesi içeren bir element_access ifadeyi Range destekliyorsa genişletilmiş dilimlenebilir koleksiyon.

Not: Model, türün bir diliminin ayarlanabilmesini gerektirmez, ancak bir tür modelin uzantısı olarak bunu destekleyebilir. dipnot

Model, tek boyutlu diziler (§12.8.12.2) ve dizeler (§12.8.12.3) için desteklenir.

Model, model semantiğini uygulayan uygun dizin oluşturucuları (§15.9) sağlayan herhangi bir sınıf, yapı veya arabirim türü tarafından desteklenebilir.

Model için örtük destek, doğrudan desteklemeyen ancak belirli bir üye deseni sağlayan türler için sağlanır (§18.4). Temel aldığı tür üyelerinin semantiği varsayıldığından , bu destek semantik tabanlı değil desen tabanlıdır; dil bu tür üyelerinin semantiğini zorlamaz veya denetlemez.

Bu yan tümcenin amaçları doğrultusunda aşağıdaki terimler tanımlanmıştır:

  • Koleksiyon, bir öğegrubunu temsil eden bir türdür.
  • Sayılabilir koleksiyon, değeri şu anda gruptaki öğelerin sayısı olan bir -valued örnek özelliği olarak sayılabilirintbir özellik sağlayan koleksiyondur. Bu özellik veya LengthCountolarak adlandırılmalıdır. Her ikisi de varsa, ilki seçilir.
  • Dizi veya dizinlenebilir tür bir koleksiyondur:
    • sayılabilir olan;
    • her öğeye tek bir gerekli bağımsız değişkenle int ifadesi kullanılarak erişilebilen başlangıç dizini, ek isteğe bağlı bağımsız değişkenlere izin verilir;
    • Her öğe bir element_access ifadesi kullanılarak da ayarlanabiliyorsa bir dizi değiştirilebilir;
    • bir öğenin başlangıç dizini, N öğelerini içeren bir dizi için dizide ondan önce gelen öğelerin sayısıdır:
      • birinci ve son öğelerin sırasıyla 0 ve N-1 dizinleri vardır ve
      • geçmiş uç dizini, son dizinden sonra varsayımsal bir öğeyi temsil eden bir dizin N değerine sahiptir.
  • Uçtan uca dizin, öğenin geçmiş uç dizinine göre bir dizi içindeki konumunu temsil eder. N öğelerini içeren bir dizi için ilk, son ve geçmiş uç dizinleri sırasıyla N, 1 ve 0'dır.
  • Aralık, bir dizi içindeki herhangi bir dizinden başlayan sıfır veya daha fazla dizinden oluşan bitişik bir çalıştırmadır.
  • Dilim, bir aralıktaki öğelerin koleksiyonudur.
  • Dilimlenebilir koleksiyon aşağıdakilerden biridir:
    • sayılabilir;
    • , sırasıyla başlangıç dizini ve öğe sayısı olmak üzere bir aralık belirten iki Slice parametre alan ve aralıktaki öğelerden oluşturulmuş yeni bir dilim döndüren bir yöntem int sağlar.

Yukarıdaki tanımlar ve Index kullanımları Range için aşağıdaki gibi genişletilmiştir:

  • Tür, bağımsız değişken yerine tek bir gerekli bağımsız değişken alan bir element_access ifadesi destekleniyorsa da bir Indexint. Ayrım gerektiğinde tür genişletilmiş dizinlenebilir olarak kabul edilir.
  • Bir yöntem yerine tek bir gerekli bağımsız değişken alan bir element_access ifadesi destekleniyorsa, bir Range tür de Slice. Ayrım gerektiğinde tür genişletilmiş dilimlenebilir olarak kabul edilir.

Bir türün sayılabilir, dizinlenebilir veya dilimlenebilir olarak sınıflandırılıp sınıflandırılmayacağı üye erişilebilirliğinin (§7.5) kısıtlamalarına tabidir ve bu nedenle türün kullanıldığı yere bağlıdır.

Örnek: Sayılabilir özelliğin ve/veya dizin oluşturucunun protected yalnızca kendi üyelerine ve türetilmiş türlere göre sıralandığı bir tür. son örnek

Bir türün sıra veya dilimlenebilir olarak nitelenebileceği gerekli üyeler devralınabilir.

Örnek: Aşağıdaki kodda

public class A
{
    public int Length { get { … } }
}

public class B : A
{
    public int this(int index) { … }
}

public class C : B
{
    public int[] Slice(int index, int count) { … }
}

Türü A sayılabilir, B bir dizidir ve C dilimlenebilir ve bir dizidir.

son örnek

Not:

  • (Erişilebilir) dizin oluşturucunun olmaması nedeniyle bir tür dizinlenebilir olmadan dilimlenebilir.
  • Bir türün dilimlenebilir ve/veya dizinlenebilir olması için türün sayılabilir olması gerekir.
  • Bir dizinin öğeleri sıra içindeki konuma göre sıralanırken, öğelerin kendi değerlerine göre, hatta sıralanabilir olmalarına gerek yoktur.

dipnot

18.2 Dizin türü

türü, System.Index başlangıç dizinini veya uçtan uca dizini temsil eden bir soyut dizini temsil eder.

    public readonly struct Index : IEquatable<Index>
    {
        public int Value { get; }
        public bool IsFromEnd { get; }

        public Index(int value, bool fromEnd = false);

        public static implicit operator Index(int value);
        public int GetOffset(int length);
        public bool Equals(Index other);
    }

Indexdeğerleri, negatif olmayan uzaklığı belirten bir intdeğerinden ve uzaklık değerinin bitişten mi (bool) yoksa başlangıçtan mı (true) olduğunu belirten bir falsedeğerinden oluşturulur. Belirtilen uzaklık negatifse bir ArgumentOutOfRangeException oluşturulur.

Örnek

Index first = new Index(0, false); // first element index
var last = new Index(1, true);     // last element index
var past = new Index(0, true);     // past-end index

Index invalid = new Index(-1);     // throws ArgumentOutOfRangeException

son örnek

başlangıç dizinleri üreten örtük bir dönüştürme intIndex ve kaynaktan bitiş dizinleri üreten dil tanımlı bir birli işleç ^ (§12.9.6) intIndex vardır.

Örnek

Yukarıdaki örnekler örtük dönüştürmeler ve birli ^ işleç kullanılarak yazılabilir:

Index first = 0; // first element index
var last = ^1;   // last element index
var past = ^0;   // past-end index

son örnek

yöntemiGetOffset, belirtilen Indexbir dizi için soyut int bir değerden somut length bir dizin değerine dönüştürür. değerinin IndexIbitişiyse, bu yöntem ile aynı değeri length - I.Valuedöndürür, aksi takdirde ile aynı değeri I.Valuedöndürür.

Bu yöntem, dönüş değerinin geçerli ile dahil aralığında 0 olup length-1 denetlemez.

Not: Sonucun beklenen kullanımı öğeleri içeren length bir dizide dizin oluşturmak olduğundan ve dizin oluşturma işleminin uygun denetimleri gerçekleştirmesi beklendiğinden hiçbir denetim belirtilmez. dipnot

Indexuygulayıcıları IEquatable<Index> ve değerleri soyut değere göre eşitlik için karşılaştırılabilir; yalnızca ilgili Index ve Value özellikler eşitse iki IsFromEnd değer eşittir. Ancak Index değerler sıralanmaz ve başka bir karşılaştırma işlemi sağlanmaz.

Not:Index değerleri soyut dizinler olduğundan sıralanmamıştır; bir başlangıç dizininden önce veya sonra gelen bir bitiş dizininin, dizi uzunluğuna başvurmadan önce mi yoksa sonra mı geldiğini belirlemek genel olarak imkansızdır. Beton endekslere dönüştürüldükten sonra, örneğin tarafından GetOffsetbu beton endeksler karşılaştırılabilir. dipnot

Indexdeğerleri, bir element_access ifadesinin (§12.8.12) argument_list doğrudan kullanılabilir:

  • dizi erişimi ve hedef tek boyutlu bir dizidir (§12.8.12.2);
  • dize erişimi (§12.8.12.3)
  • dizin oluşturucu erişimi ve hedef türün, karşılık gelen parametreleri Index (§12.8.12.4) veya değerlerin örtük olarak dönüştürülebilir olduğu Index türde bir dizin oluşturucu vardır; veya
  • dizin oluşturucu erişimi ve hedef türü örtük Index desteğin belirtildiği bir dizi düzenine uygundur (§18.4.2).

18.3 Aralık türü

türü, System.Range bir Index dizinden dizine kadar olan ancak dizin dahil Start etmeyen es soyut aralığını Endtemsil eder.

    public readonly struct Range : IEquatable<Index>
    {
        public Index Start { get; }
        public Index End { get; }

        public Range(Index start, Index end);

        public (int Offset, int Length) GetOffsetAndLength(int length);
        public bool Equals(Range other);
    }

Range değerleri iki Index değerden oluşturulur.

Örnek

Aşağıdaki örneklerde, her intbirinin değerlerini oluşturmak için Index 'den (^) ve (Index) işlecine Range örtük dönüştürme kullanılır:

var firstQuad = new Range(0, 4);  // the indices from `0` to `3`
                                  // int values impicitly convert to `Index`
var nextQuad = new Range(4, 8);   // the indices from `4` to `7`
var wholeSeq = new Range(0, ^0);  // the indices from `0` to `N-1` where `N` is the
                                  // length of the sequence wholeSeq is used with
var dropFirst = new Range(1, ^0); // the indices from `1` to `N-1`
var dropLast = new Range(0, ^1);  // the indices from `0` to `N-2`
var maybeLast = new Range(^1, 6); // the indices from `N-1` to 5
var lastTwo = new Range(^2, ^0);  // the indices from `N-2` to `N-1`

son örnek

Dil tanımlı işleç .. (§12.10) değerlerden Range bir Index değer oluşturur.

Örnek

Yukarıdaki örnekler işleci kullanılarak .. yazılabilir:

var firstQuad = 0..4;  // the indices from `0` to `3`
var nextQuad = 4..8;   // the indices from `4` to `7`
var wholeSeq = 0..^0;  // the indices from `0` to `N-1`
var dropFirst = 1..^0; // the indices from `1` to `N-1`
var dropLast = 0..^1;  // the indices from `0` to `N-2`
var maybeLast = ^1..6; // the indices from `N-1` to 5
var lastTwo = ^2..^0;  // the indices from `N-2` to `N-1`

son örnek

işlenenleri .. isteğe bağlıdır, ilk varsayılanı 0olarak, ikincisinde varsayılan değeri olarak gösterilir ^0.

Örnek

Yukarıdaki örneklerden beşi işlenenler için varsayılan değerlere bağlı olarak kısaltılabilir:

var firstQuad = ..4; // the indices from `0` to `3`
var wholeSeq = ..;   // the indices from `0` to `N-1`
var dropFirst = 1..; // the indices from `1` to `N-1`
var dropLast = ..^1; // the indices from `0` to `N-2`
var lastTwo = ^2..;  // the indices from `N-2` to `N-1`

son örnek

Bir Range değer, şu durumda L uzunluğuna göre geçerlidir:

  • özelliklerin RangeStartEnd göre ve 0 ile L arasında olan beton endeksler ve
  • için Start beton dizin, için beton dizinden büyük değildir End

Bağımsız değişken içeren yöntemGetOffsetAndLength, soyut length bir değeri tanımlama grubu tarafından temsil edilen somut Range bir değere Range dönüştürür. Range yöntemine length göre geçerli değilse, oluştururArgumentOutOfRangeException.

Döndürülen beton Range demet, formun (S, N) bir çiftidir ve burada:

  • S aralığın başlangıç uzaklığıdır; ve özelliğinin StartRangesomut dizinidir.
  • N ve özellikleri için somut dizinler arasındaki fark, aralıktaki EndStart öğelerin sayısıdır;
  • ile ilgili olarak lengthhesaplanan her iki değer de.

Somut aralık değeri sıfırsa N olur. Boş bir beton aralığı, beton geçmiş uç dizinine (S) eşit bir değere sahip olabilir, boş olmayan bir aralık olmayabilir. Range Dilimleme (§18.1) için kullanılan bir koleksiyon geçerli ve bu koleksiyonla ilgili olarak boşsa, sonuçta elde edilen dilim boş bir koleksiyondur.

Not: Yukarıdakilerin bir sonucu, sıfıra göre geçerli ve boş olan bir Rangelength değerin boş bir koleksiyonu dilimleyip boş bir dilimle sonuçlanmasıdır. Bu, koleksiyon boşsa özel durum oluşturan dizinlemeden farklıdır. son not*

Örnek

ile yukarıda GetOffSetAndLength(6)tanımlanan değişkenleri kullanma:

var (ix0, len0) = firstQuad.GetOffsetAndLength(6); // ix0 = 0, len0 = 4
var (ix1, len1) = nextQuad.GetOffsetAndLength(6);  // throws
   // ArgumentOutOfRangeException as range crosses sequence end
var (ix2, len2) = wholeSeq.GetOffsetAndLength(6);  // ix2 = 0, len2 = 6
var (ix3, len3) = dropFirst.GetOffsetAndLength(6); // ix3 = 1, len3 = 5
var (ix4, len4) = dropLast.GetOffsetAndLength(6);  // ix4 = 0, len4 = 5
var (ix5, len5) = maybeLast.GetOffsetAndLength(6); // ix5 = 5, len5 = 1
var (ix6, len6) = lastTwo.GetOffsetAndLength(6);   // ix6 = 4, len6 = 2

Range IEquatable<Range> uygulama ve değerler, soyut değere göre eşitlik için karşılaştırılabilir; yalnızca Range ilgili Start ve özelliklerin soyut değerleri eşitse iki End değer eşittir (§18.2). Ancak Range değerler sıralanmaz ve başka bir karşılaştırma işlemi sağlanmaz.

Not:Range değerleri hem soyut hem de benzersiz bir sıralama ilişkisi olmadığından sıralanmamıştır. Somut bir başlangıç ve uzunluğa dönüştürüldükten sonra, örneğin tarafından GetOffsetAndLengthbir sıralama ilişkisi tanımlanabilir. dipnot

Rangedeğerleri, bir element_access ifadesinin (§12.8.12) argument_list doğrudan kullanılabilir:

  • dizi erişimi ve hedef tek boyutlu bir dizidir (§12.8.12.2);
  • dize erişimi (§12.8.12.3);
  • dizin oluşturucu erişimi ve hedef türün, karşılık gelen parametreleri Range (§12.8.12.4) veya değerlerin örtük olarak dönüştürülebilir olduğu Range türde bir dizin oluşturucu vardır; veya
  • dizin oluşturucu erişimi (§12.8.12.4) ve hedef türü örtük Range desteğin belirtildiği bir sıra düzenine uygundur (§18.4.3).

18.4 Dizin ve Aralık için Desen tabanlı örtük destek

18.4.1 Genel

Formun bir element_access ifadesi (E[A]) ise E ; türü T varsa ve A örtük olarak veya Indexöğesine dönüştürülebilir Range tek bir ifadeyse; şu şekilde tanımlanamaz:

ardından, belirli bir desene uygunsa T ifade için örtük destek sağlanır. Bu desene uymuyorsa T derleme zamanı hatası oluşur.

18.4.2 Örtük Dizin desteği

Herhangi bir bağlamda formun element_access ifadesi (E[A]) ise ( burada E türü T vardır ve A örtük olarak dönüştürülebilir Indextek bir ifadedir) geçerli değilse (§18.4.1) aynı bağlamdaysa:

  • T bunu bir sıra olarak niteleyerek erişilebilir üyeler sağlar (§18.1); ve
  • ifadesi E[0] geçerli ve bir dizi olarak niteleyen T dizin oluşturucuyu kullanır

o zaman ifade E[A] örtük olarak desteklenecektir.

Bu Standart'ın uygulamalarını başka bir şekilde kısıtlamadan ifadenin değerlendirme sırası aşağıdakilere eşdeğer olacaktır:

  1. E değerlendirilir;
  2. A değerlendirilir;
  3. uygulamasının T gerektirdiği durumlarda countable özelliği değerlendirilir;
  4. tarafından aynı bağlamda kullanılacak int olan tabanlı dizin oluşturucunun T get veya set erişimcisi E[0] çağrılır.

18.4.3 Örtük Aralık desteği

Herhangi bir bağlamda formun element_access ifadesi (E[A]) ise ( burada E türü T vardır ve A örtük olarak dönüştürülebilir Rangetek bir ifadedir) geçerli değilse (§18.4.1) aynı bağlamdaysa:

  • Them sayılabilir hem de dilimlenebilir (§18.1) olarak nitelendiren erişilebilir üyeler sağlar

o zaman ifade E[A] örtük olarak desteklenecektir.

Bu Standart'ın uygulamalarını başka bir şekilde kısıtlamadan ifadenin değerlendirme sırası aşağıdakilere eşdeğer olacaktır:

  1. E değerlendirilir;
  2. A değerlendirilir;
  3. uygulamasının T gerektirdiği durumlarda countable özelliği değerlendirilir;
  4. Slice yöntemi T çağrılır.