Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
18.1 Allmänt
Den här satsen introducerar en modell för utökade indexerbara och utsnittsbarasamlingstyper som bygger på:
- De typer som introduceras i denna sats(System.Index§18.2) ochSystem.Range(§18.3);
- De fördefinierade unary ^-operatorerna (§12.9.6) och binära..(§12.10) och
- Uttrycket element_access .
Under modellen klassificeras en typ som:
- en samling om den representerar en grupp med elements
- en utökad indexerbar samling om den stöder ett element_access uttryck som har ett enda argumentuttryck av typen Indexsom returnerar och/eller anger ett enda element av typen, antingen efter värde eller referens, och
- en utökad utsnittsbar samling om den stöder ett element_access uttryck som har ett enda argumentuttryck av typen Rangesom returnerar en sektor av elementen av typen efter värde.
Obs! Modellen kräver inte att en sektor av typen kan anges, men en typ kan ha stöd för den som en förlängning av modellen. slutkommentar
Modellen stöds för endimensionella matriser (§12.8.12.2) och strängar (§12.8.12.3).
Modellen kan stödjas av vilken klass, struct eller gränssnittstyp som helst som tillhandahåller lämpliga indexerare (§15.9) som implementerar modellsemantiken.
Implicit stöd för modellen tillhandahålls för typer som inte direkt stöder den men som ger ett visst mönster av medlemmar (§18.4). Det här stödet är mönsterbaserat snarare än semantiskt baserat, eftersom semantiken för de typmedlemmar som den baseras på antas – språket tillämpar inte, eller kontrollerar, semantiken för dessa typmedlemmar.
I den här satsen definieras följande termer:
- En samling är en typ som representerar en grupp elements.
- En countable-samling är en som ger en räknaregenskap en intvärdeinstansegenskap vars värde är antalet element som för närvarande finns i gruppen. Den här egenskapen ska ha namnet antingenLengthellerCount. Den förra väljs om båda finns.
- En sekvens eller indexerbar typ är en samling: - som kan räknas.
- där varje element kan nås med hjälp av ett element_access uttryck med ett enda obligatoriskt intargument tillåts från-start-indexet, ytterligare valfria argument.
- En sekvens kan ändras om varje element också kan anges med hjälp av ett element_access uttryck.
- ett elements index från början är antalet element före det i sekvensen, för en sekvens som innehåller N-element : - de första och sista elementen har index på 0 respektive N-1 och
- det tidigare indexet, ett index som representerar ett hypotetiskt element efter det sista, har värdet N.
 
 
- Ett index från slutpunkt representerar ett elements position inom en sekvens i förhållande till det tidigare slutindexet. För en sekvens som innehåller N-element är de första, sista och tidigare slutindexen N, 1 respektive 0.
- Ett intervall är en sammanhängande körning med noll eller fler index som börjar vid ett index i en sekvens.
- Ett segment är en samling element inom ett intervall.
- En utsnittsbar samling är en som: - kan räknas.
- tillhandahåller en metod Slicesom tar tvåintparametrar som anger ett intervall, som är ett startindex respektive ett antal element, och returnerar en ny sektor som konstruerats från elementen i intervallet.
 
Ovanstående definitioner utökas för användning av Index och Range enligt följande:
- En typ är också en sekvens om ett element_access uttryck som tar ett enda obligatoriskt Indexargument, i stället för ettintargument, stöds. Om en skillnad krävs kallas typen utökad indexerbar.
- En typ är också utsnittsbar om ett element_access uttryck som tar ett enda obligatoriskt Rangeargument, i stället för enSlicemetod, stöds. Om en skillnad krävs kallas typen utökad utsnittsbar.
Om en typ klassificeras som räknare, indexerbar eller utsnittsbar omfattas av begränsningarna för medlemstillgänglighet (§7.5) och därför beroende på var typen används.
Exempel: En typ där den countable egenskapen och/eller indexeraren är
protectedär bara en sekvens till medlemmar av sig själv och eventuella härledda typer. slutexempel
De medlemmar som krävs för att en typ ska kvalificeras som en sekvens eller utsnittsbar kan ärvas.
Exempel: I följande kod
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) { … } }Typen
Akan räknas,Bär en sekvens ochCär utsnittsbar och en sekvens.slutexempel
Note:
- En typ kan vara utsnittsbar utan att vara indexerbar på grund av bristen på en (tillgänglig) indexerare.
- För att en typ ska vara utsnittsbar och/eller indexerbar måste typen vara räknad.
- Medan elementen i en sekvens sorteras efter position i sekvensen, behöver själva elementen inte sorteras efter deras värde eller ens ordnas.
slutkommentar
18.2 Indextypen
Typen System.Index representerar ett abstrakt index som antingen är ett index från början eller ett index från slutpunkt.
    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 värden skapas från en int, som anger den icke-negativa förskjutningen och en bool, som anger om förskjutningen kommer från slutet (true) eller start (false). Om den angivna förskjutningen är negativ utlöses en ArgumentOutOfRangeException .
Exempel
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 ArgumentOutOfRangeExceptionslutexempel
Det finns en implicit konvertering från int till Index vilken genererar index från början och en språkdefinierad unary-operator ^ (§12.9.6) från intIndex vilken genererar index från slutpunkt.
Exempel
Med implicita konverteringar och unary-operatorn
^kan exemplen ovan skrivas:Index first = 0; // first element index var last = ^1; // last element index var past = ^0; // past-end indexslutexempel
Metoden GetOffset konverterar från ett abstrakt Index värde till ett konkret int indexvärde för en sekvens av den angivna length. Om värdet Index , Iär från slutet returnerar den här metoden samma värde som length - I.Value, annars returneras samma värde som I.Value.
Den här metoden kontrollerar inte att returvärdet är inom det giltiga intervallet 0 för genom length-1 inklusive.
Not: Ingen kontroll anges eftersom den förväntade användningen av resultatet är att indexera i en sekvens med
lengthelement och att indexeringsåtgärden förväntas utföra lämpliga kontroller. slutkommentar
              Index implementeringar IEquatable<Index> och värden kan jämföras för likhet baserat på det abstrakta värdet. Två Index värden är lika om och endast om respektive Value och IsFromEnd egenskaper är lika. Värden ordnas dock Index inte och inga andra jämförelseåtgärder tillhandahålls.
Not:
Indexvärden är osorterade eftersom de är abstrakta index, är det i allmänhet omöjligt att avgöra om ett frånslutsindex kommer före eller efter ett från startindex utan referens till en sekvenslängd. När de har konverterats till konkreta index, t.ex. avGetOffset, är de konkreta indexen jämförbara. slutkommentar
              Index värden kan användas direkt i argument_list av ett element_access uttryck (§12.8.12) som är:
- en matrisåtkomst och målet är en endimensionell matris (§12.8.12.2);
- a string access (§12.8.12.3)
- en indexerares åtkomst och måltypen har en indexerare med motsvarande parametrar av antingen Indextyp (§12.8.12.4) eller av en typ somIndexvärden implicit kan konverteras till, eller
- en indexerares åtkomst och måltypen överensstämmer med ett sekvensmönster för vilket implicit Indexstöd anges (§18.4.2).
18.3 Områdestypen
Typen System.Range representerar det abstrakta intervallet av Indexes från ett Start index upp till, men inte inklusive, ett End index.
    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 värden konstrueras från två Index värden.
Exempel
I följande exempel används implicit konvertering från
inttillIndex(§18.2) och operatorn^(§12.9.6) för att skapaIndexvärdena för varjeRange: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`slutexempel
Den språkdefinierade operatorn .. (§12.10) skapar ett Range värde från Index värden.
Exempel
Med operatorn
..ovan kan exemplen ovan skrivas: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`slutexempel
Operanderna .. i är valfria, det första standardvärdet är 0, det andra standardvärdet är ^0.
Exempel
Fem av exemplen ovan kan förkortas genom att förlita sig på standardvärden för operander:
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`slutexempel
Ett Range värde är giltigt med avseende på en längd L om:
- de konkreta indexen avseende L av RangeegenskapernaStartochEndligger i intervallet 0 till L;
- betongindexet för Startär inte större än det konkreta indexet förEnd
Metoden GetOffsetAndLength med ett argument length konverterar ett abstrakt Range värde till ett konkret Range värde som representeras av tuppeln. 
              Range Om är ogiltigt med avseende length på metoden genererar ArgumentOutOfRangeException.
Den returnerade betongtuppeln Range är ett par av formen (S, N) där:
- 
              Sär startförskjutningen för intervallet, som är det konkreta indexet för egenskapenStartförRange; och
- 
              När antalet objekt i intervallet, vilket är skillnaden mellan de konkreta indexenEndför egenskaperna ochStart;
- båda värdena beräknas med avseende lengthpå .
Ett värde för betongintervall är tomt om N det är noll. Ett tomt betongområde kan ha ett S värde som är lika med betongindex (§18.1), ett icke-tomt intervall får inte. När en Range som används för att segmentera (§18.1) är en samling giltig och tom med avseende på den samlingen är den resulterande sektorn en tom samling.
Not: En följd av ovanstående är att ett
Rangevärde som är giltigt och tomt med avseende på nolllengthkan användas för att segmentera en tom samling och resultera i en tom sektor. Detta skiljer sig från indexering som genererar ett undantag om samlingen är tom. slutkommentar*
Exempel
Använd variablerna som definierats ovan med
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 implementeringar IEquatable<Range> och värden kan jämföras för likhet baserat på det abstrakta värdet. Två Range värden är lika om och endast om de abstrakta värdena för respektive Start och End egenskaperna är lika (§18.2). Värden ordnas dock Range inte och inga andra jämförelseåtgärder tillhandahålls.
Not:
Rangevärdena är osorterade eftersom de är abstrakta och det inte finns någon unik ordningsrelation. När den har konverterats till en konkret start och längd, t.ex. avGetOffsetAndLength, kan en orderrelation definieras. slutkommentar
              Range värden kan användas direkt i argument_list av ett element_access uttryck (§12.8.12) som är:
- en matrisåtkomst och målet är en endimensionell matris (§12.8.12.2);
- en strängåtkomst (§12.8.12.3);
- en indexerares åtkomst och måltypen har en indexerare med motsvarande parametrar av antingen Rangetyp (§12.8.12.4) eller av en typ somRangevärden implicit kan konverteras till, eller
- en indexerare (§12.8.12.4) och måltypen överensstämmer med ett sekvensmönster som implicit Rangestöd anges för (§18.4.3).
18.4 Mönsterbaserat implicit stöd för index och intervall
18.4.1 Allmänt
Om ett element_access uttryck (§12.8.12) i formuläret E[A], där E har typ T och A är ett enda uttryck implicit konvertibelt till Index eller Range; inte kan identifieras som:
- en matrisåtkomst (§12.8.12.2),
- en strängåtkomst (§12.8.12.3), eller
- indexerare (§12.8.12.4) som Tinte ger någon lämplig tillgänglig indexerare
sedan tillhandahålls implicit stöd för uttrycket om T det överensstämmer med ett visst mönster. Om T inte överensstämmer med det här mönstret uppstår ett kompileringsfel.
Stöd för implicit index 18.4.2
Om i något sammanhang ett element_access uttryck (§12.8.12) av formuläret E[A]; där E har typ T och A är ett enda uttryck implicit konvertibelt till Index; är inte giltigt (§18.4.1) om i samma sammanhang:
- 
              Tger tillgängliga medlemmar som kvalificerar det som en sekvens (§18.1); och
- uttrycket E[0]är giltigt och använder samma indexerare som kvalificerarTsig som en sekvens
ska uttrycket E[A] underförstått stödjas.
Utan att i övrigt begränsa genomförandet av denna standard skall utvärderingsordningen för uttrycket motsvara följande:
- 
              Eutvärderas.
- 
              Autvärderas.
- Den antalsbara egenskapen Tför utvärderas, om det krävs av implementeringen.
- get- eller set-åtkomstorn för den intbaserade indexerarenTför som skulle användas avE[0]i samma kontext anropas.
Stöd för implicit intervall 18.4.3
Om i något sammanhang ett element_access uttryck (§12.8.12) av formuläret E[A]; där E har typ T och A är ett enda uttryck implicit konvertibelt till Range; är inte giltigt (§18.4.1) om i samma sammanhang:
- 
              Ttillhandahåller tillgängliga medlemmar som kvalificerar den som både räknare ochutsnittsbar (§18.1)
ska uttrycket E[A] underförstått stödjas.
Utan att i övrigt begränsa genomförandet av denna standard skall utvärderingsordningen för uttrycket motsvara följande:
- 
              Eutvärderas.
- 
              Autvärderas.
- Den antalsbara egenskapen Tför utvärderas, om det krävs av implementeringen.
- - SlicemetodenTanropas.
ECMA C# draft specification