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ók, más néven a tömb elemei mind azonos típusúak, é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 N
esetén az indexek a befogadótól a 0
N – 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_specifier adja 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 ranggalR
rendelkező 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.Array
nem 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ő IList<T>
és annak alapfelületei közöttT[]
. Továbbá, ha implicit referencia-átalakítás S
T
történik, akkor S[]
implementálja IList<T>
a műveletet, és implicit referenciaátalakítás történik a kezdő IList<T>
és annak alapfelületei között S[]
(10.2.8. §). Ha explicit referenciakonvertálásról van szó, akkor a referenciakonvertálás S
T
a cél és annak alapfelületei között IList<T>
S[]
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ő IReadOnlyList<T>
és annak alapfelületei közöttT[]
. Továbbá, ha implicit referencia-átalakítás S
T
történik, akkor S[]
implementálja IReadOnlyList<T>
a műveletet, és implicit referenciaátalakítás történik a kezdő IReadOnlyList<T>
és annak alapfelületei között S[]
(10.2.8. §). Ha explicit referenciakonvertálásról van szó, akkor a referenciakonvertálás S
T
a cél és annak alapfelületei között IReadOnlyList<T>
S[]
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 = oa1
fordítási időt eredményez, mivel a konvertálásobject[]
IList<string>
explicit, nem implicit átalakítás. A szereposztás(IList<string>)oa1
kivételt okoz futásidőben, miveloa1
object[]
nemstring[]
a . Azonban a leadott (IList<string>)oa2
nem okoz kivételt kell dobni, miveloa2
hivatkozik 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_expression s (12.8.16.5. §) 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 A[I₁, I₂, ..., Iₓ]
element_access kifejezései (§12.8.11.2) használatával érhetők el, ahol A
egy tömbtípus kifejezése, és mindegyik Iₑ
típuskifejezésint
, uint
long
vagy ulong
implicit módon konvertálható egy vagy több ilyen típusra. A tömbelem-hozzáférés eredménye egy változó, nevezetesen az indexek által kiválasztott tömbelem.
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 B
ha implicit referenciaátalakítás (10.2.8. §) vagy explicit referenciakonvertálás (10.3.5. §) létezik A
B
, akkor ugyanez a hivatkozási átalakítás a tömbtípustól A[R]
a tömbtípusig B[R]
is létezik, ahol R
bármely adott rank_specifier (de mindkét tömbtípus esetében ugyanaz).A
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.21.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]
Fill
hozzárendelés implicit módon tartalmaz egy futásidejű ellenőrzést, amely biztosítja, hogyvalue
null
egy hivatkozás vagy hivatkozás egy olyan típusú objektumra, amely kompatibilis a tényleges elemtípussalarray
. EbbenMain
az esetben az első két meghívásFill
sikeres, de a harmadik meghívás hatásáraSystem.ArrayTypeMismatchException
az 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 dobozosint
nem 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.16.5. §):
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 mismatch
Ebben az esetben az inicializáló
y
fordítási idejű hibát eredményez, mivel a dimenzióhossz-kifejezés nem állandó, az eredmények inicializálójaz
pedig 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