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.
17.1 Általános
A tömb olyan adatstruktúra, amely számos olyan változót tartalmaz, amelyek számítási indexeken keresztül érhetők el. A tömbben található változókat a tömb elemeinek nevezzük. A tömb minden eleme ugyanazzal a típussal rendelkezik, és ezt a típust a tömb elemtípusának nevezzük.
A tömbök rangsora határozza meg az egyes tömbelemekhez társított indexek számát. A tömb rangját a tömb dimenzióinak is nevezik. Egy rangot tartalmazó tömböt egydimenziós tömbnek nevezünk. Az egynél nagyobb rangot tartalmazó tömböt többdimenziós tömbnek nevezzük. Az adott méretű többdimenziós tömböket gyakran kétdimenziós tömböknek, háromdimenziós tömböknek és így tovább nevezik. A tömbök minden dimenziójának van egy társított hossza, amely egy nullánál nagyobb vagy egyenlő egész szám. A dimenzióhosszok nem részei a tömb típusának, hanem akkor jönnek létre, ha a tömbtípus egy példánya futásidőben jön létre. A dimenzió hossza határozza meg az adott dimenzióra vonatkozó indexek érvényes tartományát: Hosszúsági dimenziók Nesetén az indexek a befogadótól a 0N – 1 befogadóig terjedhetnek. A tömb elemeinek teljes száma a tömb egyes dimenzióinak hosszának szorzata. Ha egy tömb egy vagy több dimenziója nulla hosszúságú, akkor a tömb üresnek minősül.
A tömb elemtípusa lehet tömbtípus (17.2.1. §). Az ilyen tömbök különböznek a többdimenziós tömböktől, és "szaggatott tömbök" ábrázolására használhatók.
Példa:
int[][] pascals = { new int[] {1}, new int[] {1, 1}, new int[] {1, 2, 1}, new int[] {1, 3, 3, 1} };záró példa
Minden tömbtípus egy referenciatípus (8.2. §). A tömb elemtípusa bármilyen típusú lehet, beleértve az értéktípusokat és a tömbtípusokat is.
17.2 Tömbtípusok
17.2.1 Általános
A tömbtípusok nyelvtani termelését a 8.2.1.
A tömbtípusokat non_array_type egy vagy több rank_specifierkövet.
A non_array_type minden olyan típus , amely nem maga array_type.
A tömbtípus rangját a array_type bal szélső rank_specifieradja meg: A rank_specifier azt jelzi, hogy a tömb egy egy és a rank_specifier "" jogkivonatainak száma,.
A tömbtípus elemtípusa az a típus, amely a bal szélső rank_specifier törléséből ered:
- Az űrlap
T[R]tömbtípusa egy ranggalRrendelkező tömb és egy nem tömbelem típusúT. - Az űrlap
T[R][R₁]...[Rₓ]tömbtípusa egy ranggalRés elemtípussalT[R₁]...[Rₓ]rendelkező tömb.
Valójában a rank_specifiers-eket a rendszer balról jobbra olvassa be a végső nem tömbelem-típus előtt .
Példa: A típus egydimenziós
T[][,,][,]tömb, amely a kétdimenziós tömbök háromdimenziós tömbjeiből állint. záró példa
Futtatáskor egy tömbtípus értéke vagy null hivatkozás lehet az adott tömbtípus egy példányára.
Megjegyzés: A 17.6. §-nak megfelelően az érték egy kovariant tömbtípusra való hivatkozás is lehet. végjegyzet
17.2.2 A System.Array típusa
A típus System.Array az összes tömbtípus absztrakt alaptípusa. Implicit referenciakonvertálás (10.2.8. §) létezik bármilyen tömbtípusból System.Array a System.Array. Explicit referenciakonvertálás (10.3.5.§) létezik, System.Array és bármilyen felülettípust System.Array implementál bármilyen tömbtípusra.
System.Arraynem array_type. Inkább egy class_type , amelyből az összes array_typeszármazik.
Futtatáskor a típus System.Array értéke bármilyen tömbtípus egy példányára hivatkozhat null .
17.2.3 Tömbök és az általános gyűjtőfelületek
Egy egydimenziós tömb T[] implementálja az interfészt System.Collections.Generic.IList<T> (IList<T> röviden) és alapillesztőit. Ennek megfelelően implicit átalakítás történik a kezdő T[] és annak alapfelületei közöttIList<T>. Továbbá, ha implicit referencia-átalakítás ST történik, akkor S[] implementálja IList<T> a műveletet, és implicit referenciaátalakítás történik a kezdő S[] és annak alapfelületei között IList<T> (10.2.8. §). Ha explicit referenciakonvertálásról van szó, akkor a referenciakonvertálás ST a cél és annak alapfelületei között S[]IList<T> történik (10.3.5. §).
Hasonlóképpen egy egydimenziós tömb T[] is implementálja az interfészt System.Collections.Generic.IReadOnlyList<T> (IReadOnlyList<T> röviden) és az alapillesztőit. Ennek megfelelően implicit átalakítás történik a kezdő T[] és annak alapfelületei közöttIReadOnlyList<T>. Továbbá, ha implicit referencia-átalakítás ST történik, akkor S[] implementálja IReadOnlyList<T> a műveletet, és implicit referenciaátalakítás történik a kezdő S[] és annak alapfelületei között IReadOnlyList<T> (10.2.8. §). Ha explicit referenciakonvertálásról van szó, akkor a referenciakonvertálás ST a cél és annak alapfelületei között S[]IReadOnlyList<T> történik (10.3.5. §).
Példa: Például:
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 } }A hozzárendelés
lst2 = oa1fordítási időt eredményez, mivel a konvertálásobject[]IList<string>explicit, nem implicit átalakítás. A szereposztás(IList<string>)oa1kivételt okoz futásidőben, miveloa1object[]nemstring[]a . Azonban a leadott (IList<string>)oa2nem okoz kivételt kell dobni, miveloa2hivatkozik astring[].záró példa
Amikor implicit vagy explicit referenciakonvertálásról van szó, explicit referenciakonvertálás S[]IList<T>is történik a forrásból és annak alapfelületéről IList<T>S[] (10.3.5. §).
Amikor egy tömbtípus S[] implementál IList<T>, a implementált felület egyes tagjai kivételeket okozhatnak. Az interfész implementálásának pontos viselkedése meghaladja a jelen specifikáció hatókörét.
17.3 Tömb létrehozása
A tömbpéldányokat array_creation_expressions (12.8.17.4. §) vagy egy array_initializer tartalmazó mező- vagy helyi változódeklaráció (17.7. §) hozza létre. A tömbpéldányok implicit módon is létrehozhatók egy paramétertömböt tartalmazó argumentumlista kiértékelésének részeként (15.6.2.4. §).
Tömbpéldány létrehozásakor a rendszer létrehozza az egyes dimenziók rangját és hosszát, majd állandó marad a példány teljes élettartama alatt. Más szóval nem lehet módosítani egy meglévő tömbpéldány rangját, és a méreteit sem lehet átméretezni.
A tömbpéldányok mindig tömbtípusúak. A System.Array típus olyan absztrakt típus, amely nem hozható létre.
Az array_creation_expressionáltal létrehozott tömbök elemei mindig az alapértelmezett értékükre vannak inicializálva (9.3. §).
17.4 Tömbelem-hozzáférés
A tömbelemek az űrlap element_access kifejezéseinek (12.8.12.2.§) A[I₁, I₂, ..., Iₓ] variánsával érhetők el, ahol A egy tömbtípus kifejezése, és mindegyik Iₑ típuskifejezésint, uintlongvagy ulongimplicit módon konvertálható egy vagy több ilyen típusra. A tömbhozzáférés eredménye az indexek által kiválasztott tömbelem változóhivatkozása (9.5. §).
Az egydimenziós tömbök tömbelemei egy olyan tömbelérési kifejezéssel is elérhetők, amelyben az egyetlen index, I₁egy típuskifejezés Index, Rangevagy implicit módon konvertálható egyik vagy mindkét típusra. Ha I₁ típus Index, vagy implicit módon lett átalakítva erre a típusra, akkor a tömbhozzáférés eredménye az indexérték által kiválasztott tömbelem változóhivatkozása. Ha I₁ ilyen típusú Range, vagy implicit módon lett átalakítva erre a típusra, akkor az elemhozzáférés eredménye egy új tömb, amely a tömbelemek sekély másolatából jön létre, és az elemsorrendet megtartva indexekkel Rangerendelkezik.
A tömb elemei egy utasítással foreach számba vehetők (13.9.5. §).
17.5 Tömbtagok
Minden tömbtípus örökli a típus által System.Array deklarált tagokat.
17.6 Tömb kovariancia
Bármely két reference_type esetében, és ha implicit referenciaátalakítás (A. §) vagy explicit referenciakonvertálás (B. §) létezik , akkor ugyanez a hivatkozási átalakítás a tömbtípustól A a tömbtípusig Bis létezik, ahol A[R] bármely adott B[R] (de mindkét tömbtípus esetében ugyanaz).R Ezt a kapcsolatot tömb-kovariancia néven ismerjük. A tömb kovariancia különösen azt jelenti, hogy egy tömbtípus A[R] értéke valójában egy tömbtípus B[R]egy példányára való hivatkozás lehet, feltéve, hogy implicit hivatkozási átalakítás létezik a B helyről a másikra A.
A tömbök kovariancia miatt a referencia típusú tömbök elemeihez való hozzárendelések futásidejű ellenőrzést tartalmaznak, amely biztosítja, hogy a tömbelemhez hozzárendelt érték ténylegesen engedélyezett típusú legyen (12.23.2. §).
Példa:
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); } }A metódushoz való
array[i]Fillhozzárendelés implicit módon tartalmaz egy futásidejű ellenőrzést, amely biztosítja, hogyvaluenullegy hivatkozás vagy hivatkozás egy olyan típusú objektumra, amely kompatibilis a tényleges elemtípussalarray. EbbenMainaz esetben az első két meghívásFillsikeres, de a harmadik meghívás hatásáraSystem.ArrayTypeMismatchExceptionaz első hozzárendelésarray[i]végrehajtásakor a program a következőre vált. A kivétel azért fordul elő, mert egy dobozosintnem tárolható tömbbenstring.záró példa
A tömb kovariancia nem terjed ki value_typetömbökre. Nincs például olyan átalakítás, amely lehetővé teszi, hogy a int[] rendszer egy object[].
17.7 Tömb inicializálók
Tömb inicializálók megadhatóak meződeklarációkban (15.5.§), helyi változódeklarációkban (13.6.2. §) és tömblétrehozó kifejezésekben (12.8.17.4. §):
array_initializer
: '{' variable_initializer_list? '}'
| '{' variable_initializer_list ',' '}'
;
variable_initializer_list
: variable_initializer (',' variable_initializer)*
;
variable_initializer
: expression
| array_initializer
;
A tömb inicializálói változó inicializálók sorozatából állnak, amelyeket "{" és "}" jogkivonatok, valamint "," jogkivonatok választanak el egymástól. Minden változó inicializáló egy kifejezés, vagy többdimenziós tömb esetén beágyazott tömb inicializáló.
A tömb inicializálójának környezete határozza meg az inicializálandó tömb típusát. A tömblétrehozó kifejezésben a tömbtípus közvetlenül megelőzi az inicializálót, vagy a tömb inicializálójának kifejezéseiből következtet. Egy mező- vagy változódeklarációban a tömb típusa a deklarált mező vagy változó típusa. Ha tömb inicializálót használ egy mezőben vagy változódeklarációban,
int[] a = {0, 2, 4, 6, 8};
ez egyszerűen rövidítés egy egyenértékű tömblétrehozó kifejezéshez:
int[] a = new int[] {0, 2, 4, 6, 8};
Egydimenziós tömb esetén a tömb inicializálójának kifejezéssorozatból kell állnia, amelyek mindegyike implicit módon konvertálja a tömb elemtípusát (10.2. §). A kifejezések növekvő sorrendben inicializálják a tömbelemeket, kezdve az index nullánál lévő elemével. A tömb inicializálójában lévő kifejezések száma határozza meg a létrehozandó tömbpéldány hosszát.
Példa: A fenti tömb inicializálója létrehoz egy
int[]5 hosszúságú példányt, majd inicializálja a példányt a következő értékekkel:a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8;záró példa
Többdimenziós tömb esetén a tömb inicializálójának annyi beágyazási szinttel kell rendelkeznie, mint amennyi dimenzió van a tömbben. A legkülső beágyazási szint a bal szélső dimenziónak felel meg, a legbelső beágyazási szint pedig a jobb szélső dimenziónak felel meg. A tömb minden dimenziójának hosszát a tömb inicializálójának megfelelő beágyazási szinten lévő elemek száma határozza meg. Minden beágyazott tömb inicializáló esetében az elemek számának meg kell egyeznie a többi, azonos szintű tömb inicializálóval.
Példa: A példa:
int[,] b = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};egy kétdimenziós tömböt hoz létre, amelynek bal szélső dimenziója öt, a jobb szélső dimenzióhoz pedig kettő:
int[,] b = new int[5, 2];majd inicializálja a tömbpéldányt a következő értékekkel:
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;záró példa
Ha a jobb szélső dimenziótól eltérő dimenziót nullával adnak meg, akkor a következő dimenziók is nulla hosszúságúak lesznek.
Példa:
int[,] c = {};létrehoz egy kétdimenziós tömböt, amelynek a bal szélső és a jobb szélső dimenziója is nulla hosszúságú:
int[,] c = new int[0, 0];záró példa
Ha egy tömblétrehozási kifejezés explicit dimenzióhosszokat és tömbinicializálót is tartalmaz, a hosszoknak állandó kifejezéseknek kell lenniük, és az egyes beágyazott szinteken lévő elemek számának meg kell egyeznie a megfelelő dimenzióhosszsal.
Példa: Íme néhány példa:
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 mismatchEbben az esetben az inicializáló
yfordítási idejű hibát eredményez, mivel a dimenzióhossz-kifejezés nem állandó, az eredmények inicializálójazpedig fordítási idő hibába ütközik, mert az inicializáló hossza és az elemek száma nem egyezik meg.záró példa
Megjegyzés: A C# lehetővé teszi a záró vesszőt egy array_initializer végén. Ez a szintaxis rugalmasságot biztosít a tagok hozzáadásához vagy törléséhez egy ilyen listából, és leegyszerűsíti az ilyen listák gépi létrehozását. végjegyzet
ECMA C# draft specification