Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
18.1 Általános
Ez a záradék bevezet egy modellt a kiterjesztett indexelhető és szeletelhetőgyűjteménytípusokhoz , amelyek a következőre épülnek:
- A jelen záradékban
System.Indexbevezetett típusok (18.2. §) ésSystem.Range(18.3. §); - Az előre definiált unáris
^(§12.9.6) és bináris..(§12.10) operátorok; és - A element_access kifejezés.
A modell alatt egy típus a következő besorolású:
- gyűjtemény, ha az s elemcsoportotjelöli
-
kiterjesztett indexelhető gyűjtemény, ha olyan element_access kifejezést támogat, amely egyetlen típusú argumentumkifejezéssel
Indexrendelkezik, amely a típus egyetlen elemét adja vissza és/vagy állítja be érték vagy hivatkozás alapján; és -
kiterjesztett szeletelhető gyűjtemény, ha olyan element_access kifejezést támogat, amely egyetlen típusú
Rangeargumentumkifejezéssel rendelkezik, amely a típus elemeinek szeletét adja vissza érték szerint.
Megjegyzés: A modell nem követeli meg, hogy a típus egy szelete be legyen állítva, de egy típus támogathatja azt a modell kiterjesztéseként. végjegyzet
A modell egydimenziós tömbök (§12.8.12.2) és sztringek (12.8.12.3. §) esetében támogatott.
A modellt bármely olyan osztály, szerkezet vagy interfésztípus támogathatja, amely megfelelő indexelőket (15.9. §) biztosít a modell szemantikájának implementálásával.
A modell implicit támogatása olyan típusok esetében biztosított, amelyek nem támogatják közvetlenül, de amelyek bizonyos tagmintát biztosítanak (18.4. §). Ez a támogatás nem szemantikai, hanem mintaalapú, mivel az alapul szolgáló típustagok szemantikája feltételezve van – a nyelv nem kényszeríti vagy ellenőrzi az ilyen típusú tagok szemantikáját.
A jelen záradék alkalmazásában a következő kifejezések vannak meghatározva:
- A gyűjtemény olyan típus, amely az s elemcsoportotjelöli.
- A megszámlálható gyűjtemény olyan, amely megszámlálható tulajdonságot biztosít egy
int-valued instance tulajdonságnak, amelynek értéke a csoportban jelenleg található elemek száma. Ezt a tulajdonságot vagyLengthCountvagy . Az előbbi akkor lesz kiválasztva, ha mindkettő létezik. - A sorozat vagy indexelhető típus egy gyűjtemény:
- amely megszámlálható;
- ahol minden elem egyetlen kötelező
intargumentummal rendelkező element_access-kifejezéssel érhető el, a kezdő index, további választható argumentumok engedélyezettek; - a sorozat módosítható , ha minden elem element_access kifejezéssel is beállítható;
- egy elem kezdő indexe az N elemeket tartalmazó sorozat előtt álló elemek száma:
- az első és az utolsó elem 0 és N-1 indexekkel rendelkezik, és
- A múltvégi index, amely az utolsó után egy hipotetikus elemet jelöl, az N értékkel rendelkezik.
- A végpontok közötti indexek az elemeknek a sorozaton belüli pozícióját jelölik a múltbeli indexhez képest. Az N elemeket tartalmazó sorozatok esetében az első, az utolsó és a múltbéli indexek az N, az 1 és a 0.
- A tartomány nulla vagy több index egybefüggő futtatása, amely egy sorozat bármely indexén kezdődik.
- A szelet egy tartományon belüli elemek gyűjteménye.
- A szeletelhető gyűjtemények az alábbiak:
- megszámlálható;
- egy olyan metódust
Slicebiztosít, amely kétintparamétert határoz meg, amelyek egy tartományt határoznak meg, kezdő indexként és elemszámként, és a tartomány elemeiből létrehozott új szeletet ad vissza.
A fenti definíciók a következőkre IndexRange terjednek ki:
- A típus akkor is sorozat, ha egy element_access kifejezés argumentum helyett
Indexegyetlen kötelezőintargumentumot használ. Ha különbséget kell tenni, a típust kiterjesztett indexelhetőnek nevezzük. - A típus akkor is szeletelhető , ha egy element_access kifejezés, amely egyetlen kötelező
Rangeargumentumot, inkább metódustSlicehasznál, támogatott. Ha különbséget kell tenni, a típust kiterjesztett szeletelhetőnek nevezzük.
Az, hogy egy típus megszámlálható, indexelhető vagy szeletelhetőként van-e besorolva, a tagok akadálymentességének korlátozásai (7.5. §) vonatkoznak, ezért attól függ, hogy hol használják a típust.
Példa: Az a típus, amelyben a megszámlálható tulajdonság és/vagy az indexelő
protectedcsak a tagok és a származtatott típusok sorozata. záró példa
A sorozatnak vagy szeletelhetőnek minősülő típushoz szükséges tagok öröklődhetnek.
Példa: Az alábbi kódban
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) { … } }A típus
Amegszámlálható,Begy sorozat,Cszeletelhető és sorozat.záró példa
Note:
- Egy típus (akadálymentes) indexelő hiánya miatt anélkül szeletelhető, hogy indexelhető lenne.
- Ahhoz, hogy egy típus szeletelhető és/vagy indexelhető legyen, meg kell számolni a típust.
- Bár a sorozat elemei a sorrenden belüli pozíció alapján vannak rendezve, az elemeket nem kell az értékük szerint rendezni, vagy akár rendezhetőnek is kell lenniük.
végjegyzet
18.2 Az index típusa
A System.Index típus egy absztrakt indexet jelöl, amely egy kezdő vagy egy végponti indexet jelöl.
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);
}
Index az értékek egy int, a nem negatív eltolást megjelölő és egy boolértékből jönnek létre, amely azt jelzi, hogy az eltolás a végtől (true) vagy a kezdettől (false) származik-e. Ha a megadott eltolás negatív ArgumentOutOfRangeException , a függvény eldobja.
Example
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 ArgumentOutOfRangeExceptionzáró példa
Van egy implicit konverzió intIndex , amelyből kiinduló indexeket hoz létre, és egy nyelv által definiált, nem szereplő operátor ^ (12.9.6. §), amelyből intIndex végponti indexeket állít elő.
Example
Implicit konverziók és a unary
^operátor használatával a fenti példák írhatók:Index first = 0; // first element index var last = ^1; // last element index var past = ^0; // past-end indexzáró példa
A metódus GetOffset absztrakt Index értékről egy konkrét int indexértékre konvertálja a megadott lengthsorozatot. Ha az Index érték a végponttól származik, Iakkor ez a metódus ugyanazt az értéket adja vissza, mint length - I.Valueaz érték, ellenkező esetben ugyanazt az értéket adja vissza, mint I.Valuea .
Ez a módszer nem ellenőrzi, hogy a visszatérési érték az átvitt 0 érték érvényes tartományában length-1 van-e.
Jegyzet: Nincs megadva ellenőrzés, mivel az eredmény várt használata az elemeket tartalmazó
lengthsorozatba való indexelés, és az indexelési művelet várhatóan elvégzi a megfelelő ellenőrzéseket. végjegyzet
Index az absztrakciós értéken alapuló egyenlőség esetén a megvalósítások IEquatable<Index> és értékek összehasonlíthatók; két Index érték egyenlő, ha és csak akkor, ha a megfelelő Value és IsFromEnd a tulajdonságok azonosak. Az értékek azonban Index nincsenek rendezve, és nincs más összehasonlítási művelet.
Jegyzet:
Indexaz értékek rendezetlenek, mivel absztrakciós indexek, általában lehetetlen meghatározni, hogy egy végponti index a kezdő index előtt vagy után érkezik-e, anélkül, hogy a sorozat hosszára hivatkoznának. Miután konkrét indexekké alakították át, például aGetOffsetkonkrét indexek összehasonlíthatók. végjegyzet
Indexértékek közvetlenül használhatók egy element_access kifejezés argument_list (12.8.12. §), amely a következő:
- a tömbhozzáférés és a cél egydimenziós tömb (12.8.12.2. §);
- sztringhozzáférés (§12.8.12.3)
- az indexelő hozzáférés és a céltípus rendelkezik egy indexelővel, amelynek megfelelő paraméterei vagy
Indextípusa (12.8.12.4. §), vagy olyan típus, amelyhezIndexaz értékek implicit módon átalakíthatók; vagy - az indexelő hozzáférése és a céltípus megfelel egy olyan sorozatmintának, amelyhez implicit
Indextámogatás van megadva (18.4.2. §).
18.3 A tartomány típusa
A System.Range típus az indextől az indexig Index terjedő absztrakt es tartományt Startjelöli, de nem tartalmazza az indexetEnd.
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 az értékek két Index értékből épülnek fel.
Example
Az alábbi példák a (
int) és aIndex(12.9.6. §) operátor közötti implicit átalakítást^használják azIndexegyesRangeértékek létrehozásához: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`záró példa
A nyelv által definiált operátor .. (12.10. §) értékeket Range hoz létreIndex.
Example
..Az operátor használatával a fenti példák írhatók: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`záró példa
Az operandusok .. nem kötelezőek, az első alapértelmezett 0érték, a második pedig a ^0következő.
Example
A fenti példák közül öt lerövidíthető az operandusok alapértelmezett értékeire támaszkodva:
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`záró példa
Az Rangeérték azL hosszúságra érvényes, ha:
- a tulajdonságok
RangeStartvonatkozó konkrét indexek 0 ésEndL közötti tartományban vannak; és - a konkrét index
Startnem nagyobb, mint a konkrétEnd
Az argumentumot tartalmazó metódus GetOffsetAndLength az absztrakt length értéket a rekord által képviselt konkrét Range értékké Range alakítja. Ha a Range metódus nem érvényes a length dobásokra ArgumentOutOfRangeExceptionvonatkozóan.
A visszaadott beton Range pólya az űrlap (S, N) egy párja, ahol:
-
Sa tartomány kezdő eltolása, amely a tartomány tulajdonságánakStartkonkrét indexeRange; és -
Na tartomány elemeinek száma, amely a konkrét indexek ésEndtulajdonságokStartközötti különbség; - mindkét érték kiszámítása a következőre tekintettel történik
length: .
A konkrét tartomány értéke üres , ha N nulla. Az üres betontartománynak S lehet egy olyan értéke, amely megegyezik a beton múltbeli indexének (18.1. §), a nem üres tartomány nem lehet. Ha egy Range gyűjtemény szeletelésére szolgál (18.1. §) a gyűjteményre vonatkozóan érvényes és üres, akkor az eredményként kapott szelet egy üres gyűjtemény.
Jegyzet: A fentiek egyik következménye, hogy egy
Rangenulla értékre vonatkozólengthérvényes és üres érték használható egy üres gyűjtemény szeletelésére, és üres szeletet eredményez. Ez eltér az indexeléstől, amely kivételt eredményez, ha a gyűjtemény üres. végjegyzet*
Example
A fent definiált változók használata a következővel
GetOffSetAndLength(6):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 a megvalósítások IEquatable<Range> és értékek összehasonlíthatók az absztrakt értéken alapuló egyenlőség szempontjából; két Range érték egyenlő, ha és csak akkor, ha az adott Start és End a tulajdonságok absztrakt értékei egyenlők (18.2. §). Az értékek azonban Range nincsenek rendezve, és nincs más összehasonlítási művelet.
Jegyzet:
Rangeaz értékek rendezetlenek, mivel absztraktak, és nincs egyedi rendezési kapcsolat. Miután konkrét kezdetre és hosszra alakították át, például aGetOffsetAndLengthrendezési reláció definiálható. végjegyzet
Rangeértékek közvetlenül használhatók egy element_access kifejezés argument_list (12.8.12. §), amely a következő:
- a tömbhozzáférés és a cél egydimenziós tömb (12.8.12.2. §);
- sztringhozzáférés (12.8.12.3. §);
- az indexelő hozzáférés és a céltípus rendelkezik egy indexelővel, amelynek megfelelő paraméterei vagy
Rangetípusa (12.8.12.4. §), vagy olyan típus, amelyhezRangeaz értékek implicit módon átalakíthatók; vagy - indexelő hozzáférés (12.8.12.4. §) és a céltípus megfelel egy olyan sorozatmintának, amelyhez implicit
Rangetámogatás van megadva (18.4.3. §).
18.4 Az index és a tartomány mintaalapú implicit támogatása
18.4.1 Általános
Ha az űrlap egy element_access kifejezése (E[A]), amelynek E típusa T és A egy implicit módon átalakítható Index kifejezés, nem Rangeazonosítható a következőként:
- tömbelérés (12.8.12.2. §),
- sztringhozzáférés (12.8.12.3. §), vagy
- indexelői hozzáférés (12.8.12.4. §), mivel
Tnem biztosít megfelelő akadálymentes indexelőt
akkor implicit támogatást ad a kifejezéshez, ha T megfelel egy adott mintának. Ha T nem felel meg ennek a mintának, fordítási időhiba lép fel.
18.4.2 Implicit index támogatása
Ha bármely környezetben az űrlap egy element_access kifejezése (E[A]), amelynek E típusa T és A egyetlen kifejezés implicit módon átalakíthatóIndex; érvénytelen (18.4.1. §), akkor ha ugyanabban a kontextusban:
-
Tolyan akadálymentes tagokat biztosít, aki sorozatként minősíti (18.1. §); és - a kifejezés
E[0]érvényes, és ugyanazt az indexelőt használja, amely sorozatnak minősülT
akkor a kifejezést E[A] implicit módon támogatni kell.
A jelen standard végrehajtásának egyéb korlátozása nélkül a kifejezés értékelési sorrendjének meg kell egyeznie a következőkkel:
-
Ekiértékelésre kerül; -
Akiértékelésre kerül; - a megszámlálható tulajdonság kiértékelése
T, ha a végrehajtás megköveteli; - a rendszer meghívja annak az indexelőnek a
intlekérését vagy beállításátT, amelyetE[0]ugyanabban a környezetben használna.
18.4.3 Implicit tartomány támogatása
Ha bármely környezetben az űrlap egy element_access kifejezése (E[A]), amelynek E típusa T és A egyetlen kifejezés implicit módon átalakíthatóRange; érvénytelen (18.4.1. §), akkor ha ugyanabban a kontextusban:
-
Ta számba vehető és a szeletelhetőként is jogosult akadálymentes tagok számára (18.1.§)
akkor a kifejezést E[A] implicit módon támogatni kell.
A jelen standard végrehajtásának egyéb korlátozása nélkül a kifejezés értékelési sorrendjének meg kell egyeznie a következőkkel:
-
Ekiértékelésre kerül; -
Akiértékelésre kerül; - a megszámlálható tulajdonság kiértékelése
T, ha a végrehajtás megköveteli; - metódus
SlicemeghívásaT.
ECMA C# draft specification