Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
10.1 Algemeen
Een conversie zorgt ervoor dat een expressie wordt geconverteerd naar of behandeld als een bepaald type. In het eerste geval kan een conversie een wijziging in de weergave omvatten. Conversies kunnen impliciet of expliciet zijn en dit bepaalt of een expliciete cast vereist is.
Voorbeeld: de conversie van type
intnaar typelongis bijvoorbeeld impliciet, zodat expressies van het typeintimpliciet als typelongkunnen worden behandeld. De tegenovergestelde conversie, van typelongnaar typeint, is expliciet en dus is een expliciete cast vereist.int a = 123; long b = a; // implicit conversion from int to long int c = (int) b; // explicit conversion from long to inteindvoorbeeld
Sommige conversies worden gedefinieerd door de taal. Programma's kunnen ook hun eigen conversies definiëren (§10,5).
Sommige conversies in de taal worden gedefinieerd van expressies tot typen, andere van typen tot typen. Een conversie van een type is van toepassing op alle expressies met dat type.
Voorbeeld:
enum Color { Red, Blue, Green } // The expression 0 converts implicitly to enum types Color c0 = 0; // Other int expressions need explicit conversion Color c1 = (Color)1; // Conversion from null expression (no type) to string string x = null; // Conversion from lambda expression to delegate type Func<int, int> square = x => x * x;eindvoorbeeld
10.2 Impliciete conversies
10.2.1 Algemeen
De volgende conversies worden geclassificeerd als impliciete conversies:
- Identiteitsconversies (§10.2.2)
- Impliciete numerieke conversies (§10.2.3)
- Impliciete opsommingsconversies (§10.2.4)
- Impliciete geïnterpoleerde tekenreeksconversies (§10.2.5)
- Impliciete verwijzingsconversies (§10.2.8)
- Boksen conversies (§10.2.9)
- Impliciete dynamische conversies (§10.2.10)
- Impliciete parameterconversies van type (§10.2.12)
- Impliciete conversie van constante expressies (§10.2.11)
- Door de gebruiker gedefinieerde (inclusief opgeheven) impliciete conversies (§10.2.14)
- Anonieme functieconversies (§10.2.15)
- Methodegroepconversies (§10.2.15)
- Null-letterlijke conversies (§10.2.7)
- Impliciete null-conversies (§10.2.6)
- Impliciete tupleconversies (§10.2.13)
- Standaard letterlijke conversies (§10.2.16)
- Impliciete conversies van gooien (§10.2.17)
Impliciete conversies kunnen in verschillende situaties optreden, waaronder functielidvocations (§12.6.6), cast-expressies (§12.9.8) en toewijzingen (§12.23).
De vooraf gedefinieerde impliciete conversies slagen altijd en veroorzaken nooit dat uitzonderingen worden gegenereerd.
Opmerking: Goed ontworpen door de gebruiker gedefinieerde impliciete conversies moeten ook deze kenmerken vertonen. eindnotitie
Voor conversie zijn de typen object converteerbaar dynamic (§10.2.2).
Dynamische conversies (§10.2.10) zijn echter alleen van toepassing op expressies van het type dynamic (§8.2.4).
10.2.2 Identiteitsconversie
Een identiteitsconversie wordt geconverteerd van elk type naar hetzelfde type of een type dat tijdens runtime gelijkwaardig is. Een van de redenen dat deze conversie bestaat, is dat een type T of een expressie van het type T kan worden gezegd om converteerbaar te zijn naar T zichzelf. De volgende identiteitsconversies bestaan:
- Tussen
TenT, voor elk typeT. - Tussen
TenT?voor elk verwijzingstypeT. - Tussen
objectendynamic. - Tussen alle tupletypen met dezelfde arity en het bijbehorende samengestelde
ValueTuple<...>type, wanneer er een identiteitsconversie bestaat tussen elk paar overeenkomende elementtypen. - Tussen typen die zijn samengesteld uit hetzelfde algemene type, waarbij er een identiteitsconversie bestaat tussen elk bijbehorend typeargument.
Voorbeeld: Hieronder ziet u de recursieve aard van de derde regel:
(int a , string b) t1 = (1, "two"); (int c, string d) t2 = (3, "four"); // Identity conversions exist between // the types of t1, t2, and t3. var t3 = (5, "six"); t3 = t2; t2 = t1; var t4 = (t1, 7); var t5 = (t2, 8); // Identity conversions exist between // the types of t4, t5, and t6. var t6 =((8, "eight"), 9); t6 = t5; t5 = t4;De typen tuples
t1ent2t3hebben allemaal twee elementen: eenintgevolgd door eenstring. Tuple-elementtypen kunnen zichzelf door tuples, zoals int4,t5ent6. Er bestaat een identiteitsconversie tussen elk paar bijbehorende elementtypen, inclusief geneste tuples, waardoor er een identiteitsconversie bestaat tussen de typen tuplest4,t5ent6.eindvoorbeeld
Alle identiteitsconversies zijn symmetrisch. Als er een identiteitsconversie van T₁ naar T₂bestaat, bestaat er een identiteitsconversie van T₂ naar T₁. Twee typen zijn converteerbare identiteiten wanneer er een identiteitsconversie tussen twee typen bestaat.
In de meeste gevallen heeft een identiteitsconversie geen effect tijdens runtime. Aangezien drijvendekommabewerkingen echter met een hogere precisie kunnen worden uitgevoerd dan voorgeschreven door hun type (§8.3.7), kunnen de toewijzing van hun resultaten leiden tot een verlies van precisie, en expliciete casts zijn gegarandeerd om de precisie te beperken tot wat wordt voorgeschreven door het type (§12.9.8).
10.2.3 Impliciete numerieke conversies
De impliciete numerieke conversies zijn:
- Van
sbytenaarshort,int,long, , ,floatofdoubledecimal. - Van
bytenaarshort,ushort, ,int,uint, ,long,ulong, ,float, ,doubleofdecimal. - Van
shortnaarint,long,float, ofdoubledecimal. - Van
ushortnaarint,uint,long, ,ulong, ,float, ofdouble.decimal - Van
intnaarlong,float, ofdoubledecimal. - Van
uintnaarlong,ulong,float, ofdoubledecimal. - Van
longnaarfloat,doubleofdecimal. - Van
ulongnaarfloat,doubleofdecimal. - Van
charnaarushort,int, ,uint,long, ,ulong, ,float, ,doubleofdecimal. - Van
floatindouble.
Conversies vanint, uintlong of van en ulongfloat naar long of ulong naar double kunnen leiden tot verlies van precisie, maar zullen nooit een verlies van grootte veroorzaken. De andere impliciete numerieke conversies verliezen nooit informatie.
Er zijn geen vooraf gedefinieerde impliciete conversies naar het char type, dus waarden van de andere integrale typen worden niet automatisch geconverteerd naar het char type.
10.2.4 Impliciete opsommingsconversies
Met een impliciete opsommingsconversie kan een constant_expression (§12,25) met een geheel getal en de waarde nul worden geconverteerd naar een enum_type en naar een nullable_value_type waarvan het onderliggende type een enum_type is. In het laatste geval wordt de conversie geëvalueerd door te converteren naar de onderliggende enum_type en het resultaat te verpakken (§8.3.12).
10.2.5 Impliciete geïnterpoleerde tekenreeksconversies
Met een impliciete geïnterpoleerde tekenreeksconversie kan een interpolated_string_expression (§12.8.3
Wanneer deze conversie wordt toegepast, wordt een tekenreekswaarde niet samengesteld uit de geïnterpoleerde tekenreeks. In plaats daarvan wordt er een exemplaar van System.FormattableString gemaakt, zoals verder beschreven in §12.8.3.
10.2.6 Impliciete null-conversies
De impliciete null-conversies zijn de conversies die nullable zijn (§10.6.1) die zijn afgeleid van impliciete vooraf gedefinieerde conversies.
10.2.7 Null-letterlijke conversies
Er bestaat een impliciete conversie van de null letterlijke waarde naar een verwijzingstype of null-waardetype. Deze conversie produceert een null-verwijzing als het doeltype een verwijzingstype is of de null-waarde (§8.3.12) van het opgegeven type null-waarde.
10.2.8 Impliciete verwijzingsconversies
De impliciete verwijzingsconversies zijn:
- Van elke reference_type tot
objectendynamic. - Van elke class_type
Stot een class_typeT, dieSwordt verstrekt, is afgeleid vanT. - Van elke class_type
Stot elke interface_typeT, geleverdSimplementeertT. - Van elke interface_type
Stot een interface_typeT, dieSwordt verstrekt, is afgeleid vanT. - Van een array_type
Smet een elementtypeSᵢtot een array_typeTmet een elementtypeTᵢ, mits alle volgende waar zijn:-
SenTverschilt alleen in elementtype. Met andere woorden,SenThebben hetzelfde aantal dimensies. - Er bestaat een impliciete verwijzingsconversie van
SᵢnaarTᵢ.
-
- Van een enkeldimensionaal matrixtype
S[]naarSystem.Collections.Generic.IList<T>,System.Collections.Generic.IReadOnlyList<T>en de bijbehorende basisinterfaces, mits er een impliciete identiteit of verwijzingsconversie vanSnaarT. - Van elke array_type naar
System.Arrayen de interfaces die worden geïmplementeerd. - Van elke delegate_type naar
System.Delegateen de interfaces die worden geïmplementeerd. - Van de letterlijke waarde null (§6.4.5.7) tot elk verwijzingstype.
- Van elke reference_type naar een reference_type
Tals deze een impliciete identiteit of verwijzingsconversie heeft naar een enT₀een identiteitsconversieT₀naar . - Van elke reference_type naar een interface of gedelegeerd type
Tals deze een impliciete identiteit of verwijzingsconversie heeft naar een interface of gedelegeerd typeT₀enT₀variantie-converteerbaar is (§19.2.3.3) naarT. - Impliciete conversies met typeparameters die bekend zijn als referentietypen. Zie §10.2.12 voor meer informatie over impliciete conversies met betrekking tot typeparameters.
De impliciete verwijzingsconversies zijn die conversies tussen reference_types die kunnen worden bewezen altijd te slagen en daarom geen controles tijdens runtime vereisen.
Verwijzingsconversies, impliciet of expliciet, wijzigen nooit de referentiële identiteit van het object dat wordt geconverteerd.
Opmerking: Met andere woorden, terwijl een verwijzingsconversie het type van de verwijzing kan wijzigen, wordt nooit het type of de waarde van het object waarnaar wordt verwezen, gewijzigd. eindnotitie
10.2.9 Boksing conversies
Met een boksconversie kan een value_type impliciet worden geconverteerd naar een reference_type. De volgende boksconversies bestaan:
- Van elke value_type tot het type
object. - Van elke value_type tot het type
System.ValueType. - Van elke enum_type tot het type
System.Enum. - Van elke non_nullable_value_type tot alle interface_type die door de non_nullable_value_type zijn geïmplementeerd.
- Van elke
- Van elke non_nullable_value_type tot elke interface_type
Izodanig dat er een boksconversie van de non_nullable_value_type naar een andere interface_typeI₀, enI₀is variantie-converteerbaar (§19.2.3.3) totI. - Van elke nullable_value_type naar een reference_type waar een boksconversie van het onderliggende type van de nullable_value_type naar de reference_type is.
- Van een typeparameter die niet bekend is als referentietype voor elk type, zodat de conversie is toegestaan door §10.2.12.
Het boksen van een waarde die niet nullable is, bestaat uit het toewijzen van een objectexemplaar en het kopiëren van de waarde naar dat exemplaar.
Als u een waarde van een nullable_value_type boksen, wordt een null-verwijzing gegenereerd als dit de null-waarde is (HasValue onwaar) of het resultaat van het uitpakken en boksen van de onderliggende waarde, anders.
Opmerking: Het boksproces kan worden voorgesteld in termen van het bestaan van een boksklasse voor elk waardetype. Denk bijvoorbeeld aan een
struct Simplementatie van een interfaceI, met een boksklasse genaamdS_Boxing.interface I { void M(); } struct S : I { public void M() { ... } } sealed class S_Boxing : I { S value; public S_Boxing(S value) { this.value = value; } public void M() { value.M(); } }Het boksen van een waarde
vvan het typeSbestaat nu uit het uitvoeren van de expressienew S_Boxing(v)en het retourneren van het resulterende exemplaar als een waarde van het doeltype van de conversie. De verklaringenS s = new S(); object box = s;kan worden beschouwd als vergelijkbaar met:
S s = new S(); object box = new S_Boxing(s);Het hierboven beschreven type boksen bestaat niet daadwerkelijk. In plaats daarvan heeft een waarde in een vak van het type
Shet runtimetypeSen een runtimetypecontrole met behulp van deisoperator met een waardetype als de rechteroperand test of de linkeroperand een vakkenversie van de rechteroperand is. Bijvoorbeeld:int i = 123; object box = i; if (box is int) { Console.Write("Box contains an int"); }voert het volgende uit:
Box contains an intEen boksconversie impliceert het maken van een kopie van de waarde die in een vak wordt geplaatst. Dit verschilt van een conversie van een . Bijvoorbeeld: het volgende
struct Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } class A { void M() { Point p = new Point(10, 10); object box = p; p.x = 20; Console.Write(((Point)box).x); } }voert de waarde 10 uit op de console omdat de impliciete boksbewerking die plaatsvindt in de toewijzing van
pdeboxwaarde diepmoet worden gekopieerd, wordt uitgevoerd. WasPointeen in plaats daarvan gedeclareerdclass, de waarde 20 zou uitvoer zijn omdatpenboxzou verwijzen naar hetzelfde exemplaar.De analogie van een boksklasse mag niet worden gebruikt als meer dan een nuttig hulpmiddel voor het weergeven van hoe boksen werkt conceptueel. Er zijn talloze subtiele verschillen tussen het gedrag dat door deze specificatie wordt beschreven en het gedrag dat zou resulteren uit boksen op precies deze manier.
eindnotitie
10.2.10 Impliciete dynamische conversies
Er bestaat een impliciete dynamische conversie van een expressie van het type dynamisch naar elk type T. De conversie is dynamisch gebonden §12.3.3, wat betekent dat een impliciete conversie wordt gezocht tijdens runtime vanaf het uitvoeringstype van de expressie naar T. Als er geen conversie wordt gevonden, wordt er een runtime-uitzondering gegenereerd.
Deze impliciete conversie schendt schijnbaar het advies in het begin van §10.2 dat een impliciete conversie nooit een uitzondering mag veroorzaken. Het is echter niet de conversie zelf, maar het vinden van de conversie die de uitzondering veroorzaakt. Het risico van runtime-uitzonderingen is inherent aan het gebruik van dynamische binding. Als dynamische binding van de conversie niet gewenst is, kan de expressie eerst worden geconverteerd naar objecten vervolgens naar het gewenste type.
Voorbeeld: Hieronder ziet u impliciete dynamische conversies:
object o = "object"; dynamic d = "dynamic"; string s1 = o; // Fails at compile-time – no conversion exists string s2 = d; // Compiles and succeeds at run-time int i = d; // Compiles but fails at run-time – no conversion existsDe toewijzingen aan
s2enibeide maken gebruik van impliciete dynamische conversies, waarbij de binding van de bewerkingen wordt onderbroken tot de runtime. Tijdens runtime worden impliciete conversies gezocht van het runtimetype vand(string) naar het doeltype. Er wordt een conversie gevonden naarstring, maar niet naarint.eindvoorbeeld
10.2.11 Impliciete constante expressieconversies
Een impliciete conversie van constante expressies maakt de volgende conversies mogelijk:
- Een constant_expression (§12.25) van het type
intkan worden geconverteerd naar typesbyte, ,byteshortushort, ,uintofulong, mits de waarde van het constant_expression binnen het bereik van het doeltype valt. - Een constant_expression van het type kan worden geconverteerd naar het type
longulong, mits de waarde van de constant_expression niet negatief is.
10.2.12 Impliciete conversies met typeparameters
Voor een die bekend staat als referentietype (T), bestaan de volgende impliciete verwijzingsconversies (§10.2.8):
- Van
Ttot de effectieve basisklasseC, vanTnaar elke basisklasse vanCen vanTelke interface die wordt geïmplementeerd doorC. - Van
Tnaar een interface_typeIinTde effectieve interfaceset en vanTelke basisinterface vanI. - Van
Tnaar een typeparameterUdieTafhankelijkUis van (§15.2.5).Opmerking: Aangezien
Tbekend is dat het een verwijzingstype is,Tis het runtimetypeUaltijd een referentietype, zelfs alsUhet niet bekend is dat het een verwijzingstype tijdens het compileren is. eindnotitie - Van de letterlijke waarde null (§6.4.5.7) tot T.
Voor een die nietTals referentietype §15.2.5, worden de volgende conversies beschouwd als boksconversies (T) tijdens het compileren. Als dit een waardetype is, T wordt de conversie tijdens runtime uitgevoerd als boksconversie. Als dit een verwijzingstype is, T wordt de conversie tijdens runtime uitgevoerd als een impliciete verwijzingsconversie of identiteitsconversie.
- Van
Ttot de effectieve basisklasseC, vanTnaar elke basisklasse vanCen vanTelke interface die wordt geïmplementeerd doorC.Opmerking:
Cdit is een van de typenSystem.Object,System.ValueTypeofSystem.Enum(andersTzou het een verwijzingstype zijn). eindnotitie - Van
Tnaar een interface_typeIinTde effectieve interfaceset en vanTelke basisinterface vanI.
Voor een type_parameterT die niet bekend is als een verwijzingstype, is er een impliciete conversie van T naar een typeparameter U opgegevenT, afhankelijk Uvan.
T Als dit een waardetype is en U een verwijzingstype is, wordt de conversie uitgevoerd als een boksconversie. Tijdens runtime, als beide T en U waardetypen zijn, T en U noodzakelijkerwijs hetzelfde type zijn en er geen conversie wordt uitgevoerd. Als dit een verwijzingstype is, TU is dit noodzakelijkerwijs ook een referentietype en wordt de conversie uitgevoerd als impliciete verwijzingsconversie of identiteitsconversie (§15.2.5).
De volgende impliciete conversies bestaan voor een bepaalde typeparameter T:
- Van
Tnaar een verwijzingstypeSals het een impliciete conversie naar een verwijzingstypeS₀heeft enS₀een identiteitsconversieSnaar . Tijdens de uitvoering wordt de conversie op dezelfde manier uitgevoerd als de conversie naarS₀. - Van
Tnaar een interfacetypeIals deze een impliciete conversie naar een interfacetypeI₀heeft enI₀variantie converteert naarI(§19.2.3.3). Als dit een waardetype is,Twordt de conversie tijdens runtime uitgevoerd als boksconversie. Anders wordt de conversie uitgevoerd als een impliciete verwijzingsconversie of identiteitsconversie.
In alle gevallen zorgen de regels ervoor dat een conversie wordt uitgevoerd als een boksconversie als en alleen als de conversie tijdens runtime van een waardetype naar een verwijzingstype is.
10.2.13 Impliciete tupleconversies
Een impliciete conversie bestaat van een tuple-expressie E naar een tupletype T als E dezelfde arity heeft als T en een impliciete conversie bestaat van elk element in E het bijbehorende elementtype in T. De conversie wordt uitgevoerd door een exemplaar van Thet bijbehorende System.ValueTuple<...> type te maken en elk van de velden te initialiseren in volgorde van links naar rechts door de bijbehorende tuple-elementexpressie te evalueren, Ete converteren naar het bijbehorende elementtype van het gebruik van T de impliciete conversie gevonden en het veld te initialiseren met het resultaat.
Als een elementnaam in de tuple-expressie niet overeenkomt met een overeenkomende elementnaam in het tuple-type, wordt een waarschuwing afgegeven.
Voorbeeld:
(int, string) t1 = (1, "One"); (byte, string) t2 = (2, null); (int, string) t3 = (null, null); // Error: No conversion (int i, string s) t4 = (i: 4, "Four"); (int i, string) t5 = (x: 5, s: "Five"); // Warning: Names are ignoredDe declaraties van
t1,t2t4ent5zijn allemaal geldig, omdat impliciete conversies bestaan van de elementexpressies naar de bijbehorende elementtypen. De declaratie vant3is ongeldig, omdat er geen conversie is vannullnaarint. De declaratie vant5veroorzaakt een waarschuwing omdat de elementnamen in de tuple-expressie verschillen van die in het tuple-type.eindvoorbeeld
10.2.14 Door de gebruiker gedefinieerde impliciete conversies
Een door de gebruiker gedefinieerde impliciete conversie bestaat uit een optionele standaard impliciete conversie, gevolgd door de uitvoering van een door de gebruiker gedefinieerde impliciete conversieoperator, gevolgd door een andere optionele standaard impliciete conversie. De exacte regels voor het evalueren van door de gebruiker gedefinieerde impliciete conversies worden beschreven in §10.5.4.
10.2.15 Anonieme functieconversies en methodegroepconversies
Anonieme functies en methodegroepen hebben geen typen in en van zichzelf, maar ze kunnen impliciet worden geconverteerd naar gedelegeerde typen. Daarnaast kunnen sommige lambda-expressies impliciet worden geconverteerd naar expressiestructuurtypen. Anonieme functieconversies worden uitgebreid beschreven in §10.7 en methodegroepconversies in §10.8.
10.2.16 Standaard letterlijke conversies
Er bestaat een impliciete conversie van een default_literal (§12.8.21) tot elk type. Deze conversie produceert de standaardwaarde (§9.3) van het uitgestelde type.
10.2.17 Impliciete conversies voor gooien
Hoewel throw-expressies geen type hebben, kunnen ze impliciet worden geconverteerd naar elk type.
10.2.18 Switch-expressieconversie
Er is een impliciete conversie van een switch_expression (§12.11) naar elk type T waarvoor een impliciete conversie bestaat van elke switch_expression_arm switch_expression_arm_expression naar .T
10.3 Expliciete conversies
10.3.1 Algemeen
De volgende conversies worden geclassificeerd als expliciete conversies:
- Alle impliciete conversies (§10.2)
- Expliciete numerieke conversies (§10.3.2)
- Expliciete opsommingsconversies (§10.3.3)
- Expliciete null-conversies (§10.3.4)
- Expliciete tupleconversies (§10.3.6)
- Expliciete verwijzingsconversies (§10.3.5)
- Expliciete interfaceconversies
- Conversies uitpakken (§10.3.7)
- Expliciete typeparameterconversies (§10.3.8)
- Door de gebruiker gedefinieerde expliciete conversies (§10.3.9)
Expliciete conversies kunnen optreden in cast-expressies (§12.9.8).
De set expliciete conversies bevat alle impliciete conversies.
Opmerking: Hiermee kan bijvoorbeeld een expliciete cast worden gebruikt wanneer er een impliciete identiteitsconversie bestaat, om de selectie van een bepaalde methode overbelast te houden. eindnotitie
De expliciete conversies die geen impliciete conversies zijn, zijn conversies die niet altijd kunnen worden bewezen, conversies die mogelijk informatie verliezen en conversies tussen typen voldoende verschillend zijn om expliciete notatie te verdienen.
10.3.2 Expliciete numerieke conversies
De expliciete numerieke conversies zijn de conversies van een numeric_type naar een andere numeric_type waarvoor een impliciete numerieke conversie (§10.2.3) nog niet bestaat:
- Van
sbytenaarbyte,ushort,uint, ofulongchar. - Van
bytenaarsbyteofchar. - Van
shortnaarsbyte,byte,ushort, , ,uintofulongchar. - Van
ushortnaarsbyte,byte, ofshortchar. - Van
intnaarsbyte,byte,short, ,ushort, ,uint, ofulong.char - Van
uintnaarsbyte,byte,short, , ,ushortofintchar. - Van
longnaarsbyte,byte, ,short,ushort, ,int, ,uint, ,ulongofchar. - Van
ulongnaarsbyte,byte, ,short,ushort, ,int, ,uint, ,longofchar. - Van
charnaarsbyte,byteofshort. - Van
floatnaarsbyte,byte, ,short,ushort, ,int,uint, ,long,ulong, , , ,charofdecimal. - Van
doublenaarsbyte,byte, ,short,ushort, ,intuint,long, ,ulong,char, , offloatdecimal. - Van
decimalnaarsbyte,byte, ,short,ushort, ,intuint,long, ,ulong,char, , offloatdouble.
Omdat de expliciete conversies alle impliciete en expliciete numerieke conversies bevatten, is het altijd mogelijk om van elke numeric_type te converteren naar andere numeric_type met behulp van een cast-expressie (§12.9.8).
De expliciete numerieke conversies verliezen mogelijk informatie of veroorzaken mogelijk uitzonderingen. Een expliciete numerieke conversie wordt als volgt verwerkt:
- Voor een conversie van een integraal type naar een ander integraal type is de verwerking afhankelijk van de context van de overloopcontrole (§12.8.20) waarin de conversie plaatsvindt:
- In een
checkedcontext slaagt de conversie als de waarde van de bronoperand binnen het bereik van het doeltype valt, maar eenSystem.OverflowExceptionals de waarde van de bronoperand buiten het bereik van het doeltype valt. - In een
uncheckedcontext slaagt de conversie altijd en gaat het als volgt.- Als het brontype groter is dan het doeltype, wordt de bronwaarde afgekapt door de 'extra' belangrijkste bits te verwijderen. Het resultaat wordt vervolgens behandeld als een waarde van het doeltype.
- Als het brontype dezelfde grootte heeft als het doeltype, wordt de bronwaarde behandeld als een waarde van het doeltype
- In een
- Voor een conversie van
decimaleen integraal type wordt de bronwaarde afgerond op nul naar de dichtstbijzijnde integrale waarde en wordt deze integrale waarde het resultaat van de conversie. Als de resulterende integrale waarde buiten het bereik van het doeltype valt, wordt er eenSystem.OverflowExceptiongegenereerd. - Voor een conversie van
floatofdoublenaar een integraal type is de verwerking afhankelijk van de context van overloopcontrole (§12.8.20) waarin de conversie plaatsvindt:- In een gecontroleerde context gaat de conversie als volgt:
- Als de waarde van de operand NaN of oneindig is, wordt er een
System.OverflowExceptiongegenereerd. - Anders wordt de bronoperand naar nul afgerond op de dichtstbijzijnde integrale waarde. Als deze integrale waarde binnen het bereik van het doeltype valt, is deze waarde het resultaat van de conversie.
- Anders wordt er een
System.OverflowExceptiongegooid.
- Als de waarde van de operand NaN of oneindig is, wordt er een
- In een niet-gecontroleerd context slaagt de conversie altijd en gaat het als volgt.
- Als de waarde van de operand NaN of oneindig is, is het resultaat van de conversie een niet-opgegeven waarde van het doeltype.
- Anders wordt de bronoperand naar nul afgerond op de dichtstbijzijnde integrale waarde. Als deze integrale waarde binnen het bereik van het doeltype valt, is deze waarde het resultaat van de conversie.
- Anders is het resultaat van de conversie een niet-opgegeven waarde van het doeltype.
- In een gecontroleerde context gaat de conversie als volgt:
- Voor een conversie van
doublenaarfloat, wordt dedoublewaarde afgerond op de dichtstbijzijndefloatwaarde. Als dedoublewaarde te klein is om als eenfloatweer te geven, wordt het resultaat nul met hetzelfde teken als de waarde. Als de grootte van dedoublewaarde te groot is om als eenfloatweer te geven, wordt het resultaat oneindig met hetzelfde teken als de waarde. Als dedoublewaarde NaN is, is het resultaat ook NaN. - Voor een conversie van
floatofdoublenaardecimal, wordt de bronwaarde indien nodig geconverteerd naardecimalweergave en afgerond op het dichtstbijzijnde getal (§8.3.8).- Als de bronwaarde te klein is om als een
decimalweer te geven, wordt het resultaat nul, waarbij het teken van de oorspronkelijke waarde behouden blijft alsdecimalu ondertekende nulwaarden ondersteunt. - Als de grootte van de bronwaarde te groot is om weer te geven als een
decimal, of als die waarde oneindig is, behoudt het resultaat het teken van de oorspronkelijke waarde, als de decimale weergave infinities ondersteunt; anders wordt er een System.OverflowException gegenereerd. - Als de bronwaarde NaN is, is het resultaat NaN als de decimale weergave NaN ondersteunt; anders wordt er een System.OverflowException gegenereerd.
- Als de bronwaarde te klein is om als een
- Voor een conversie van
decimalnaar offloatdoublewordt dedecimalwaarde afgerond op het dichtstbijzijnde ofdoublede dichtstbijzijndefloatwaarde. Als de grootte van de bronwaarde te groot is om weer te geven in het doeltype of als die waarde oneindig is, behoudt het resultaat oneindigheid het teken van de oorspronkelijke waarde. Als de bronwaarde NaN is, is het resultaat NaN. Hoewel deze conversie precisie kan verliezen, wordt er nooit een uitzondering gegenereerd.
Opmerking: het type is niet vereist om infinities of NaN-waarden te ondersteunen, maar kan dit wel doen. Het
decimalbereik is mogelijk kleiner dan het bereikfloatendouble, maar is niet gegarandeerd. Voordecimalrepresentaties zonder infiniteiten of NaN-waarden, en met een kleiner bereik danfloat, is het resultaat van een conversie vandecimalof naar offloatdoublenooit oneindig of NaN. eindnotitie
10.3.3 Expliciete opsommingsconversies
De expliciete opsommingsconversies zijn:
- Van
sbyte,byte,short,ushort, ,int,uint,longulongchar,float, ofdoubledecimalnaar een enum_type. - Van elke enum_type tot , , , ,
sbytebyte, ,short, , ,ushortintuintlongof .ulongcharfloatdoubledecimal - Van enum_type tot andere enum_type.
Een expliciete opsommingsconversie tussen twee typen wordt verwerkt door alle deelnemende enum_type als het onderliggende type van die enum_type te behandelen en vervolgens een impliciete of expliciete numerieke conversie tussen de resulterende typen uit te voeren.
voorbeeld van: Bij een enum_type
Emet een onderliggend typeintwordt een conversie vanEnaarbyteverwerkt als een expliciete numerieke conversie (§10.3.2) vaninttotbyteen een conversie vanbytenaarEwordt verwerkt als een impliciete numerieke conversie (§10.2.3) vanbytetotint. eindvoorbeeld
10.3.4 Expliciete null-conversies
De expliciete null-conversies zijn de conversies die nullable zijn (§10.6.1) die zijn afgeleid van expliciete en impliciete vooraf gedefinieerde conversies.
10.3.5 Expliciete verwijzingsconversies
De expliciete verwijzingsconversies zijn:
- Van object naar andere reference_type.
- Van elke class_type
Stot elke class_typeT, opgegevenSis een basisklasse vanT. - Van elke tot een
S, wordt niet verzegeld enTgeleverd wordt niet geïmplementeerdS. - Van elke tot een
S, die wordt geleverd, wordt niet verzegeld of geleverdTimplementeertT. - Van elke interface_type
Stot een interface_typeT,Sdie niet is afgeleid vanT. - Van een array_type
Smet een elementtypeSᵢtot een array_typeTmet een elementtypeTᵢ, mits alle volgende waar zijn:-
SenTverschilt alleen in elementtype. Met andere woorden,SenThebben hetzelfde aantal dimensies. - Er bestaat een expliciete verwijzingsconversie van
SᵢnaarTᵢ.
-
- Van
System.Arrayen de interfaces die worden geïmplementeerd, op elke array_type. - Van ééndimensionale array_type tot , en de basisinterfaces ervan, mits er een identiteitsconversie of expliciete verwijzingsconversie van
S[]naarSystem.Collections.Generic.IList<T>.System.Collections.Generic.IReadOnlyList<T>ST - Van
System.Collections.Generic.IList<S>,System.Collections.Generic.IReadOnlyList<S>en hun basisinterfaces naar een enkeldimensionaal matrixtypeT[], mits er een identiteitsconversie of expliciete verwijzingsconversie vanSnaar T is. - Van
System.Delegateen de interfaces die worden geïmplementeerd in elke delegate_type. - Van een verwijzingstype naar een verwijzingstype
STals het een expliciete verwijzingsconversie vanSeen verwijzingstype naar een verwijzingstypeT₀heeft enT₀er een identiteitsconversie vanT₀naarT. - Van een verwijzingstype naar een interface of gedelegeerdentype
STals er een expliciete verwijzingsconversie vanSeen interface of gedelegeerde isT₀enT₀een variantie-converteerbaar is naarTofTvariantie converteert naarT₀§19.2.3.3. - Van
D<S₁...Sᵥ>waarD<T₁...Tᵥ>D<X₁...Xᵥ>een algemeen gemachtigde type is,D<S₁...Sᵥ>is niet compatibel met of identiekD<T₁...Tᵥ>aan, en voor elk type parameterXᵢvanDde volgende bewaring:- Als
Xᵢis invariant,Sᵢdan is identiek aanTᵢ. - Als
Xᵢcovariant is, is er een identiteitsconversie, impliciete verwijzingsconversie of expliciete verwijzingsconversie vanSᵢnaarTᵢ. - Als
Xᵢdit contravariant is,Sᵢzijn zeTᵢidentiek of beide verwijzingstypen.
- Als
- Expliciete conversies met typeparameters die bekend zijn als referentietypen. Zie §10.3.8 voor meer informatie over expliciete conversies met typeparameters.
De expliciete verwijzingsconversies zijn die conversies tussen reference_types waarvoor runtimecontroles zijn vereist om ervoor te zorgen dat ze correct zijn.
De waarde van de bronoperand moet nulleen expliciete verwijzingsconversie zijn, of het type object waarnaar wordt verwezen door de bronoperand moet een type zijn dat kan worden geconverteerd naar het doeltype door een impliciete verwijzingsconversie (§10.2.8). Als een expliciete verwijzingsconversie mislukt, wordt er een System.InvalidCastException gegenereerd.
Opmerking: verwijzingsconversies, impliciet of expliciet, wijzigen nooit de waarde van de verwijzing zelf (§8.2.1), alleen het type. Het type of de waarde van het object waarnaar wordt verwezen, wordt ook niet gewijzigd. eindnotitie
10.3.6 Expliciete tuple-conversies
Een expliciete conversie bestaat van een tuple-expressie E naar een tupletype T als E dezelfde arity heeft als T en een impliciete of expliciete conversie bestaat van elk element in E het bijbehorende elementtype in T. De conversie wordt uitgevoerd door een exemplaar van Thet bijbehorende System.ValueTuple<...> type te maken en elk van de velden te initialiseren in volgorde van links naar rechts door de bijbehorende tuple-elementexpressie te evalueren, Ete converteren naar het bijbehorende elementtype van het gebruik van T de expliciete conversie gevonden en het veld te initialiseren met het resultaat.
10.3.7 Conversies uitpakken
Met een conversie van postvak UIT kan een reference_type expliciet worden geconverteerd naar een value_type. De volgende conversies voor het opheffen van postvakken bestaan:
- Van het type
objecttot elke value_type. - Van het type
System.ValueTypetot elke value_type. - Van het type
System.Enumtot elke enum_type. - Van elke interface_type naar een non_nullable_value_type waarmee de interface_type wordt geïmplementeerd.
- Van elke naar een
Iwaar een conversie van een interface_type naar hetI₀en een identiteitsconversie van naarI. - Van elke interface_type
Inaar een non_nullable_value_type waarbij de conversie van een interface_typeI₀naar de non_nullable_value_type ongedaan wordt gesteld enI₀ofwel variance_convertible is ofIIeen variantie-converteerbaar is naarI₀(§19.2.3.3). - Van elke reference_type naar een willekeurige nullable_value_type waarbij de conversie van reference_type naar de onderliggende non_nullable_value_type van de nullable_value_type is uitgeschakeld.
- Van een typeparameter die niet bekend is als een waardetype voor elk type, zodat de conversie is toegestaan door §10.3.8.
Een uitbox-bewerking voor een non_nullable_value_type bestaat uit het eerst controleren of het objectexemplaar een waarde in het vak van de opgegeven non_nullable_value_type is en vervolgens de waarde uit het exemplaar kopieert.
Als u de vakken op een nullable_value_type opheffen, wordt de null-waarde van de nullable_value_type als de bronoperand is null, of het verpakte resultaat van het uitpakken van het objectexemplaren op het onderliggende type van de nullable_value_type anders.
Opmerking: Verwijzend naar de imaginaire boksklasse die wordt beschreven in §10.2.9, bestaat een uitboxingconversie van een objectvak naar een value_type
Sbestaat uit het uitvoeren van de expressie((S_Boxing)box).value. De verklaringenobject box = new S(); S s = (S)box;conceptueel overeenkomen met
object box = new S_Boxing(new S()); S s = ((S_Boxing)box).value;eindnotitie
De waarde van de bronoperand is een verwijzing naar een vakkenwaarde van die non_nullable_value_type voor een conversie van het postvak uit te schakelen naar een gegeven non_nullable_value_type die in runtime kan slagen. Als de bronoperand een null gegooid wordtSystem.NullReferenceException. Als de bronoperand een verwijzing naar een niet-compatibel object is, wordt er een System.InvalidCastException gegenereerd.
De waarde van de bronoperand moet null zijn of een verwijzing naar een vakkenwaarde van de onderliggende non_nullable_value_type van de nullable_value_type voor een conversie van het postvak uitpakken naar een gegeven nullable_value_type. Als de bronoperand een verwijzing naar een niet-compatibel object is, wordt er een System.InvalidCastException gegenereerd.
10.3.8 Expliciete conversies met typeparameters
Voor een die bekend staat als referentietype (T), bestaan de volgende expliciete verwijzingsconversies (§10.3.5):
- Van de effectieve basisklasse
CvanTvan en naarTelke basisklasse vanCnaarT. - Van elke interface_type tot
T. - Van
Tnaar een interface_typeIopgegeven is er nog geen impliciete verwijzingsconversie vanTnaarI. - Van een tot
Uvoorwaarde datTafhankelijk isTvan (U).Opmerking: Aangezien
Thet een verwijzingstype is, binnen het bereik vanT, is het runtimetype van u altijd een verwijzingstype, zelfs alsUdit niet bekend is als een verwijzingstype tijdens het compileren. eindnotitie
Voor een die nietTals een referentietype (§15.2.5), worden de volgende conversies met betrekking tot het inpakken van conversies (T beschouwd. Als dit een waardetype is, T wordt de conversie tijdens runtime uitgevoerd als een conversie voor het opheffen van postvakken. Als dit een verwijzingstype is, T wordt de conversie uitgevoerd als expliciete verwijzingsconversie of identiteitsconversie.
- Van de effectieve basisklasse
CvanTvan en naarTelke basisklasse vanCnaarT.Opmerking: C is een van de typen
System.Object,System.ValueTypeofSystem.Enum(andersTzou het een verwijzingstype zijn). eindnotitie - Van elke interface_type tot
T.
Voor een die nietTals referentietype (§15.2.5), bestaan de volgende expliciete conversies:
- Van
Tnaar een interface_typeImits er nog geen impliciete conversie vanTnaarI. Deze conversie bestaat uit een impliciete boksconversie (§10.2.9) vanTnaarobjectgevolgd door een expliciete verwijzingsconversie vanobjectnaarI. Als dit een waardetype is,Twordt de conversie uitgevoerd als een boksconversie, gevolgd door een expliciete verwijzingsconversie. Als dit een verwijzingstype is,Twordt de conversie uitgevoerd als een expliciete verwijzingsconversie. - Van een typeparameter
UtotTopgegeven dieTafhankelijkUis van (§15.2.5).TAls dit een waardetype is enUeen verwijzingstype is, wordt de conversie uitgevoerd als een conversie voor het uitpakken van de vakken. Tijdens runtime, als beideTenUwaardetypen zijn,TenUnoodzakelijkerwijs hetzelfde type zijn en er geen conversie wordt uitgevoerd. Als dit een verwijzingstype is,Tis ditUnoodzakelijkerwijs ook een verwijzingstype en wordt de conversie uitgevoerd als een expliciete verwijzingsconversie of identiteitsconversie.
In alle gevallen zorgen de regels ervoor dat een conversie wordt uitgevoerd als een conversie voor het opheffen van postvakken als en alleen als de conversie tijdens runtime van een verwijzingstype naar een waardetype is.
De bovenstaande regels staan geen directe expliciete conversie toe van een niet-gekoppelde typeparameter naar een niet-interfacetype, wat mogelijk verrassend is. De reden voor deze regel is om verwarring te voorkomen en de semantiek van dergelijke conversies duidelijk te maken.
Voorbeeld: Bekijk de volgende declaratie:
class X<T> { public static long F(T t) { return (long)t; // Error } }Als de directe expliciete conversie van
tnaarlongis toegestaan, kan men gemakkelijk verwachten dat datX<int>.F(7)zou retourneren7L. Dit zou echter niet zo zijn, omdat de standaard numerieke conversies alleen worden overwogen wanneer de typen numeriek zijn op bindingstijd. Om de semantiek duidelijk te maken, moet het bovenstaande voorbeeld in plaats daarvan worden geschreven:class X<T> { public static long F(T t) { return (long)(object)t; // Ok, but will only work when T is long } }Deze code wordt nu gecompileerd, maar het uitvoeren
X<int>.F(7)zou vervolgens een uitzondering genereren tijdens runtime, omdat een boxedintniet rechtstreeks kan worden geconverteerd naar eenlong.eindvoorbeeld
10.3.9 Door de gebruiker gedefinieerde expliciete conversies
Een door de gebruiker gedefinieerde expliciete conversie bestaat uit een optionele standaard expliciete conversie, gevolgd door de uitvoering van een door de gebruiker gedefinieerde impliciete of expliciete conversieoperator, gevolgd door een andere optionele standaard expliciete conversie. De exacte regels voor het evalueren van door de gebruiker gedefinieerde expliciete conversies worden beschreven in §10.5.5.
10.4 Standaardconversies
10.4.1 Algemeen
De standaardconversies zijn die vooraf gedefinieerde conversies die kunnen optreden als onderdeel van een door de gebruiker gedefinieerde conversie.
10.4.2 Standaard impliciete conversies
De volgende impliciete conversies worden geclassificeerd als standaard impliciete conversies:
- Identiteitsconversies (§10.2.2)
- Impliciete numerieke conversies (§10.2.3)
- Impliciete null-conversies (§10.2.6)
- Null-letterlijke conversies (§10.2.7)
- Impliciete verwijzingsconversies (§10.2.8)
- Boksen conversies (§10.2.9)
- Impliciete conversie van constante expressies (§10.2.11)
- Impliciete conversies met typeparameters (§10.2.12)
De standaard impliciete conversies sluiten specifiek door de gebruiker gedefinieerde impliciete conversies uit.
10.4.3 Standaard expliciete conversies
De expliciete standaardconversies zijn alle standaard impliciete conversies plus de subset van de expliciete conversies waarvoor een tegenovergestelde impliciete standaardconversie bestaat.
Opmerking: Met andere woorden, als er een standaard impliciete conversie bestaat van een type
Anaar een typeB, bestaat er een standaard expliciete conversie van typeAnaar typeBen van type naar typeBA. eindnotitie
10.5 Door de gebruiker gedefinieerde conversies
10.5.1 Algemeen
Met C# kunnen de vooraf gedefinieerde impliciete en expliciete conversies worden uitgebreid met door de gebruiker gedefinieerde conversies. Door de gebruiker gedefinieerde conversies worden geïntroduceerd door conversieoperators (§15.10.4) in klasse- en structtypen te declareren.
10.5.2 Toegestane door de gebruiker gedefinieerde conversies
Met C# kunnen alleen bepaalde door de gebruiker gedefinieerde conversies worden gedeclareerd. Het is met name niet mogelijk om een reeds bestaande impliciete of expliciete conversie opnieuw te definiëren.
Voor een bepaald brontype S en doeltype T, als S of T null-waardetypen zijn, kunt u de onderliggende typen toestaan S₀ en T₀ raadplegen, anders S₀ en T₀ zijn ze gelijk aan S en T respectievelijk. Een klasse of struct mag alleen een conversie van een brontype S naar een doeltype T declareren als alle volgende waar zijn:
-
S₀enT₀zijn verschillende typen. - Of
S₀is het klasse-T₀of structtype waarin de operatordeclaratie plaatsvindt. -
S₀NochT₀een interface_type. - Met uitzondering van door de gebruiker gedefinieerde conversies bestaat er geen conversie van
SnaarTof vanT.S
De beperkingen die van toepassing zijn op door de gebruiker gedefinieerde conversies worden opgegeven in §15.10.4.
10.5.3 Evaluatie van door de gebruiker gedefinieerde conversies
Een door de gebruiker gedefinieerde conversie converteert een bronexpressie, die mogelijk een brontype heeft, naar een ander type, het doeltype genoemd. Evaluatie van een door de gebruiker gedefinieerde conversiecentra voor het vinden van de meest specifieke door de gebruiker gedefinieerde conversieoperator voor de bronexpressie en het doeltype. Deze bepaling wordt onderverdeeld in verschillende stappen:
- De set klassen en structs zoeken waaruit door de gebruiker gedefinieerde conversieoperators worden overwogen. Deze set bestaat uit het brontype en de basisklassen, als het brontype bestaat, samen met het doeltype en de bijbehorende basisklassen. Voor dit doel wordt ervan uitgegaan dat alleen klassen en structs door de gebruiker gedefinieerde operators kunnen declareren en dat niet-klassetypen geen basisklassen hebben. Als het bron- of doeltype ook een nullable-value-type is, wordt het onderliggende type in plaats daarvan gebruikt.
- Vanuit die set typen bepalen welke door de gebruiker gedefinieerde en lifted conversieoperators van toepassing zijn. Voor een conversieoperator die van toepassing is, moet het mogelijk zijn om een standaardconversie (§10.4) uit te voeren van de bronexpressie naar het operandtype van de operator, en moet het mogelijk zijn om een standaardconversie uit te voeren van het resultaattype van de operator naar het doeltype.
- Bepaal uit de set van toepasselijke door de gebruiker gedefinieerde operators welke operator ondubbelzinnig de meest specifieke operator is. In het algemeen is de meest specifieke operator de operator waarvan het operandtype het dichtst bij de bronexpressie ligt en waarvan het resultaattype het dichtst bij het doeltype ligt. Door de gebruiker gedefinieerde conversieoperators hebben de voorkeur boven lifted conversieoperators. De exacte regels voor het tot stand brengen van de meest specifieke door de gebruiker gedefinieerde conversieoperator worden gedefinieerd in de volgende subclauses.
Zodra een meest specifieke door de gebruiker gedefinieerde conversieoperator is geïdentificeerd, bestaat de daadwerkelijke uitvoering van de door de gebruiker gedefinieerde conversie uit maximaal drie stappen:
- Voer eerst, indien nodig, een standaardconversie van de bronexpressie uit naar het operandtype van de door de gebruiker gedefinieerde of lifted conversieoperator.
- Roep vervolgens de door de gebruiker gedefinieerde of lifted conversieoperator aan om de conversie uit te voeren.
- Ten slotte voert u, indien nodig, een standaardconversie uit van het resultaattype van de door de gebruiker gedefinieerde conversieoperator naar het doeltype.
Evaluatie van een door de gebruiker gedefinieerde conversie omvat nooit meer dan één door de gebruiker gedefinieerde of lifted conversieoperator. Met andere woorden, een conversie van type S naar type T voert nooit eerst een door de gebruiker gedefinieerde conversie van S naar X en vervolgens een door de gebruiker gedefinieerde conversie van X naar T.
- Exacte definities van evaluatie van door de gebruiker gedefinieerde impliciete of expliciete conversies worden gegeven in de volgende subclauses. De definities maken gebruik van de volgende termen:
- Als een impliciete standaardconversie (§10.4.2) bestaat van een type
Atot een typeB, en alsAnochBinterface_typezijn, wordtAdoorBomvatten enBA. - Als een impliciete standaardconversie (§10.4.2) bestaat uit een expressie
Etot een typeB, en als nochBnoch het typeE(indien deze een heeft) interface_typezijn, wordtEgeacht te worden opgenomen inBenBwordt gezegd datEomvat. - Het meest omvattende type in een set typen is het ene type dat alle andere typen in de set omvat. Als geen enkel type alle andere typen omvat, heeft de set geen meest omvattend type. In intuïtievere termen is het meest omvattende type het 'grootste' type in de set: het ene type waarnaar elk van de andere typen impliciet kan worden geconverteerd.
- Het meest omvattende type in een set typen is het ene type dat wordt omvat door alle andere typen in de set. Als er geen enkel type is opgenomen in alle andere typen, heeft de set geen meest omvattend type. In intuïtievere termen is het meest omvattende type het kleinste type in de set: het ene type dat impliciet kan worden geconverteerd naar elk van de andere typen.
10.5.4 Door de gebruiker gedefinieerde impliciete conversies
Een door de gebruiker gedefinieerde impliciete conversie van een expressie E naar een type T wordt als volgt verwerkt:
Bepaal de typen
SenS₀T₀.- Als
Eu een type hebt, laatSu dat type zijn. - Als
SofTnull-waardetypen zijn, laatSᵢen zijn ze de onderliggende typen, laat zeTᵢanders toeSᵢenTᵢST, respectievelijk. - Als
SᵢofTᵢtypeparameters zijn, laatS₀en zijn ze hun effectieve basisklassen, laat zeT₀anders toeS₀enT₀SₓTᵢ, respectievelijk.
- Als
Zoek de set typen,
Dvan waaruit door de gebruiker gedefinieerde conversieoperators worden overwogen. Deze set bestaat uitS₀(indienS₀aanwezig en is een klasse of struct), de basisklassenS₀van (indienS₀aanwezig en is een klasse) enT₀(alsT₀het een klasse of struct is). Er wordt alleen een type aan de setDtoegevoegd als er geen identiteitsconversie naar een ander type bestaat dat al in de set is opgenomen.Zoek de set toepasselijke door de gebruiker gedefinieerde en lifted conversieoperators.
UDeze set bestaat uit de door de gebruiker gedefinieerde en opgeheven impliciete conversieoperators die zijn gedeclareerd door de klassen of structs inDdie worden omgezet van een type dat omvatEtot een type dat wordt omvat doorT. AlsUdeze leeg is, is de conversie niet gedefinieerd en treedt er een compileertijdfout op.- Indien
Saanwezig en een van de operators inUconverteren vanS, danSₓisS. - Anders is dit
Sₓhet meest omvattende type in de gecombineerde set brontypen van de operators inU. Als precies één meest omvattend type niet kan worden gevonden, is de conversie dubbelzinnig en treedt er een compilatiefout op.
- Indien
Zoek het meest specifieke doeltype,
Tₓvan de operators inU:- Als een van de operators die
Uworden geconverteerd naarT, danTₓisT. - Anders is het
Tₓmeest omvattende type in de gecombineerde set doeltypen van de operators inU. Als precies één meest omvattend type niet kan worden gevonden, is de conversie dubbelzinnig en treedt er een compilatiefout op.
- Als een van de operators die
Zoek de meest specifieke conversieoperator:
- Als
Uer precies één door de gebruiker gedefinieerde conversieoperator is waaruit wordt geconverteerdSₓTₓ, is dit de meest specifieke conversieoperator. -
UAls dit niet precies één lifted conversieoperator bevat die vanSₓTₓwaaruit wordt geconverteerd, is dit de meest specifieke conversieoperator. - Anders is de conversie dubbelzinnig en treedt er een compilatietijdfout op.
- Als
Pas ten slotte de conversie toe:
- Als E het type
Sₓnog niet heeft, wordt er een standaard impliciete conversie vanEnaarSₓuitgevoerd. - De meest specifieke conversieoperator wordt aangeroepen om van te converteren
SₓnaarTₓ. - Als
Tₓdat nietThet is, wordt een standaard impliciete conversie vanTₓnaarTuitgevoerd.
- Als E het type
Een door de gebruiker gedefinieerde impliciete conversie van een type S naar een type T bestaat als een door de gebruiker gedefinieerde impliciete conversie bestaat van een variabele van het type S naar T.
10.5.5 Door de gebruiker gedefinieerde expliciete conversies
Een door de gebruiker gedefinieerde expliciete conversie van een expressie E naar een type T wordt als volgt verwerkt:
- Bepaal de typen
SenS₀T₀.- Als
Eu een type hebt, laatSu dat type zijn. - Als
SofTnull-waardetypen zijn, laatSᵢen zijn ze de onderliggende typen, laat zeTᵢanders toeSᵢenTᵢST, respectievelijk. - Als
SᵢofTᵢtypeparameters zijn, laatS₀en zijn ze hun effectieve basisklassen, laat zeT₀anders toeS₀enT₀SᵢTᵢ, respectievelijk.
- Als
- Zoek de set typen,
Dvan waaruit door de gebruiker gedefinieerde conversieoperators worden overwogen. Deze set bestaat uitS₀(indienS₀aanwezig en is een klasse of struct), de basisklassenS₀van (indienS₀aanwezig en is een klasse),T₀(alsT₀dit een klasse of struct is) en de basisklassen vanT₀(alsT₀dit een klasse is). Er wordt alleen een type aan de setDtoegevoegd als er geen identiteitsconversie naar een ander type bestaat dat al in de set is opgenomen. - Zoek de set toepasselijke door de gebruiker gedefinieerde en lifted conversieoperators.
UDeze set bestaat uit de door de gebruiker gedefinieerde en opgeheven impliciete of expliciete conversieoperators die zijn gedeclareerd door de klassen of structs inDdie conversie van een type dat omvatEof omvat doorS(indien aanwezig) naar een type dat omvat of omvat doorT. AlsUdeze leeg is, is de conversie niet gedefinieerd en treedt er een compileertijdfout op. - Zoek het meest specifieke brontype,
Sₓvan de operators inU:- Als S bestaat en een van de operators die worden
Ugeconverteerd vanS, danSₓisS. - Als een van de operators die
Uworden geconverteerd van typen die omvattenE, is ditSₓanders het meest omvattende type in de gecombineerde set brontypen van deze operators. Als er geen meest omvattend type kan worden gevonden, is de conversie dubbelzinnig en treedt er een compilatiefout op. - Anders is het
Sₓmeest omvattende type in de gecombineerde set brontypen van de operators inU. Als precies één meest omvattend type niet kan worden gevonden, is de conversie dubbelzinnig en treedt er een compilatiefout op.
- Als S bestaat en een van de operators die worden
- Zoek het meest specifieke doeltype,
Tₓvan de operators inU:- Als een van de operators die
Uworden geconverteerd naarT, danTₓisT. - Als een van de operators die
Uworden geconverteerd naar typen die zijn opgenomen inT, is ditTₓanders het meest omvattende type in de gecombineerde set doeltypen van deze operators. Als precies één meest omvattend type niet kan worden gevonden, is de conversie dubbelzinnig en treedt er een compilatiefout op. -
TₓAnders is het meest omvattende type in de gecombineerde set doeltypen van de operators inU. Als er geen meest omvattend type kan worden gevonden, is de conversie dubbelzinnig en treedt er een compilatiefout op.
- Als een van de operators die
- Zoek de meest specifieke conversieoperator:
- Als U precies één door de gebruiker gedefinieerde conversieoperator bevat die van
SₓTₓwaaruit wordt geconverteerd, is dit de meest specifieke conversieoperator. -
UAls dit niet precies één lifted conversieoperator bevat die vanSₓTₓwaaruit wordt geconverteerd, is dit de meest specifieke conversieoperator. - Anders is de conversie dubbelzinnig en treedt er een compilatietijdfout op.
- Als U precies één door de gebruiker gedefinieerde conversieoperator bevat die van
- Pas ten slotte de conversie toe:
- Als
Edit nog niet het typeSₓheeft, wordt een standaard expliciete conversie van E naarSₓuitgevoerd. - De meest specifieke door de gebruiker gedefinieerde conversieoperator wordt aangeroepen om te converteren van
SₓnaarTₓ. - Als
Tₓdat nietTzo is, wordt een standaard expliciete conversie vanTₓnaarTuitgevoerd.
- Als
Een door de gebruiker gedefinieerde expliciete conversie van een type S naar een type T bestaat als een door de gebruiker gedefinieerde expliciete conversie bestaat van een variabele van het type S naar T.
10.6 Conversies met null-typen
10.6.1 Nullable Conversies
Met een null-conversie kan een vooraf gedefinieerde conversie worden gebruikt voor een niet-null-waardetype dat ook kan worden gebruikt met de null-vorm van dat type. Voor elk van de vooraf gedefinieerde impliciete of expliciete conversies die worden geconverteerd van een niet-null-waardetype S naar een niet-null-waardetype T (§10.2.2, §10.2.3, §10.2.4, §10.2.11, §10.3.2 en §10.3.3), bestaan de volgende null-conversies:
- Een impliciete of expliciete conversie van
S?naarT? - Een impliciete of expliciete conversie van
SnaarT? - Een expliciete conversie van
S?naarT.
Een null-conversie wordt zelf geclassificeerd als een impliciete of expliciete conversie.
Bepaalde null-conversies worden geclassificeerd als standaardconversies en kunnen worden uitgevoerd als onderdeel van een door de gebruiker gedefinieerde conversie. Met name worden alle impliciete null-conversies geclassificeerd als standaard impliciete conversies (§10.4.2) en deze expliciete null-conversies die voldoen aan de vereisten van §10.4.3 worden geclassificeerd als standaard expliciete conversies.
Evaluatie van een null-conversie op basis van een onderliggende conversie van S naar gaat T als volgt:
- Als de conversie die null kan worden uitgevoerd, van
S?naarT?:- Als de bronwaarde null is (
HasValueeigenschap isfalse), is het resultaat de null-waarde van het typeT?. - Anders wordt de conversie geëvalueerd als uitpakken van
S?naarS, gevolgd door de onderliggende conversie vanSnaarT, gevolgd door een terugloop vanTnaarT?.
- Als de bronwaarde null is (
- Als de null-conversie van
Snaar isT?, wordt de conversie geëvalueerd als de onderliggende conversie vanSnaarTgevolgd door een terugloop vanTnaarT?. - Als de null-conversie van
S?naar isT, wordt de conversie geëvalueerd als uitpakken vanS?naarSgevolgd door de onderliggende conversie vanSnaarT.
10.6.2 Lifted conversies
Gezien een door de gebruiker gedefinieerde conversieoperator die wordt geconverteerd van een niet-nullable waardetype S naar een niet-nullable waardetypeT, bestaat er een lifted conversieoperator die wordt geconverteerd van S? naar T?. Deze opgetilde conversieoperator voert een uitgepakt van S? naar S gevolgd door de door de gebruiker gedefinieerde conversie van S naar T gevolgd door een terugloop van T naar T?, behalve dat een null-waarde die S? rechtstreeks wordt geconverteerd naar een null-waarde .T? Een lifted conversion operator heeft dezelfde impliciete of expliciete classificatie als de onderliggende door de gebruiker gedefinieerde conversieoperator.
10.7 Anonieme functieconversies
10.7.1 Algemeen
Een anonymous_method_expression of lambda_expression wordt geclassificeerd als anonieme functie (§12.21). De expressie heeft geen type, maar kan impliciet worden geconverteerd naar een compatibel gemachtigdentype. Sommige lambda-expressies kunnen ook impliciet worden geconverteerd naar een compatibel type expressiestructuur.
Een anonieme functie F is met name compatibel met een opgegeven gemachtigde:D
- Als
Fdit een anonymous_function_signature bevat,DFmoet u hetzelfde aantal parameters hebben. - Als
Fdit geen anonymous_function_signature bevat,Dkan het zijn dat er nul of meer parameters van een willekeurig type zijn, zolang er geen parameter vanDeen uitvoerparameter is. - Als
Fer een expliciet getypte parameterlijst is, heeft elke parameterDdezelfde modifiers als de bijbehorende parameter inFen bestaat er een identiteitsconversie tussen de bijbehorende parameter inF. - Als
Fer een impliciet getypte parameterlijst is,Dheeft u geen verwijzings- of uitvoerparameters. - Als de hoofdtekst
Feen expressie is, en ofwelDeen ongeldig retourtype heeft ofFasynchroon is enDeen«TaskType»retourtype heeft (§15.14.1), dan is de hoofdtekst vanFeen geldige expressie, wanneer elke parameter vanDhet type heeft van de corresponderende parameter inF(w.r.t §12), die als statement_expression (§13.7) is toegestaan. - Als de hoofdtekst
Fvan een blok is en eenDongeldig retourtype heeft ofFasynchroon is enDeen«TaskType»retourtype heeft, krijgt elke parameterFhet type van de overeenkomstige parameter inD, dan is de hoofdtekstFvan een geldig blok (w.r.t §13.3) waarin geenreturninstructie een expressie aangeeft. - Als de hoofdtekst van
Feen expressie is en niet-asynchroonFis enDeen niet-voidretourtypeTheeft, ofFasynchroon is enDeen«TaskType»<T>retourtype heeft (§15.14.1), dan wanneer aan elke parameter vanFde type wordt gegeven van de overeenkomstige parameter inD, is de lichaam vanFeen geldige expressie (w.r.t §12) die impliciet wordt geconverteerd naarT. - Als de hoofdtekst
Fvan een blok is en niet-asynchroonFis enDeen niet-ongeldig retourtypeTheeft, asynchroon is enFeenDretourtype heeft, krijgt elke parameter«TaskType»<T>het type van de bijbehorende parameter inF, dan is de hoofdtekstDeen geldig instructieblok (w.r.tF) met een niet-bereikbaar eindpunt waarin elke retourinstructie een expressie aangeeft die impliciet converteerbaar is naar .
Voorbeeld: In de volgende voorbeelden ziet u de volgende regels:
delegate void D(int x); D d1 = delegate { }; // Ok D d2 = delegate() { }; // Error, signature mismatch D d3 = delegate(long x) { }; // Error, signature mismatch D d4 = delegate(int x) { }; // Ok D d5 = delegate(int x) { return; }; // Ok D d6 = delegate(int x) { return x; }; // Error, return type mismatch delegate void E(out int x); E e1 = delegate { }; // Error, E has an output parameter E e2 = delegate(out int x) { x = 1; }; // Ok E e3 = delegate(ref int x) { x = 1; }; // Error, signature mismatch delegate int P(params int[] a); P p1 = delegate { }; // Error, end of block reachable P p2 = delegate { return; }; // Error, return type mismatch P p3 = delegate { return 1; }; // Ok P p4 = delegate { return "Hello"; }; // Error, return type mismatch P p5 = delegate(int[] a) // Ok { return a[0]; }; P p6 = delegate(params int[] a) // Error, params modifier { return a[0]; }; P p7 = delegate(int[] a) // Error, return type mismatch { if (a.Length > 0) return a[0]; return "Hello"; }; delegate object Q(params int[] a); Q q1 = delegate(int[] a) // Ok { if (a.Length > 0) return a[0]; return "Hello"; };eindvoorbeeld
Voorbeeld: De volgende voorbeelden gebruiken een algemeen gemachtigdentype
Func<A,R>dat een functie vertegenwoordigt die een argument van het typeAgebruikt en een waarde van het typeRretourneert:delegate R Func<A,R>(A arg);In de opdrachten
Func<int,int> f1 = x => x + 1; // Ok Func<int,double> f2 = x => x + 1; // Ok Func<double,int> f3 = x => x + 1; // Error Func<int, Task<int>> f4 = async x => x + 1; // Okde parameter en retourtypen van elke anonieme functie worden bepaald op basis van het type variabele waaraan de anonieme functie is toegewezen.
De eerste toewijzing converteert de anonieme functie naar het type gemachtigde
Func<int,int>omdat, wanneerxhet typeintis opgegeven,x + 1een geldige expressie is die impliciet kan worden omgezet in typeint.Op dezelfde manier converteert de tweede opdracht de anonieme functie naar het gemachtigde type Func<int, dubbel> omdat het resultaat van
x + 1(van het typeint) impliciet converteert naar typedouble.De derde toewijzing is echter een compilatiefout omdat, wanneer
xhet opgegeven typedoubleis, het resultaat vanx + 1(van het typedouble) niet impliciet converteerbaar is naar typeint.De vierde toewijzing converteert de anonieme asynchrone functie naar het gemachtigde type
Func<int, Task<int>>omdat het resultaat vanx + 1(van het typeint) impliciet wordt omgezet in het effectieve retourtypeintvan de asynchrone lambda, dat een retourtypeTask<int>heeft.eindvoorbeeld
Een lambda-expressie F is compatibel met een expressiestructuurtype Expression<D> als F deze compatibel is met het type Dgemachtigde. Dit geldt niet voor anonieme methoden, alleen lambda-expressies.
Anonieme functies kunnen invloed hebben op overbelastingsresolutie en deelnemen aan typedeductie. Zie §12.6 voor meer informatie.
10.7.2 Evaluatie van anonieme functieconversies naar gedelegeerde typen
De conversie van een anonieme functie naar een gemachtigdentype produceert een gemachtigde instantie die verwijst naar de anonieme functie en de (mogelijk lege) set vastgelegde buitenste variabelen die actief zijn op het moment van de evaluatie. Wanneer de gemachtigde wordt aangeroepen, wordt de hoofdtekst van de anonieme functie uitgevoerd. De code in de hoofdtekst wordt uitgevoerd met behulp van de set vastgelegde buitenste variabelen waarnaar wordt verwezen door de gemachtigde. Een delegate_creation_expression (§12.8.17.5) kan worden gebruikt als een alternatieve syntax voor het converteren van een anonieme methode naar een delegate type.
De aanroeplijst van een gemachtigde die is geproduceerd uit een anonieme functie bevat één vermelding. De exacte doelobject- en doelmethode van de gemachtigde zijn niet opgegeven. In het bijzonder is het niet opgegeven of het doelobject van de gemachtigde is null, de this waarde van het insluitende functielid of een ander object.
Conversies van semantisch identieke anonieme functies met dezelfde (mogelijk lege) set vastgelegde instanties van buitenvariabelen zijn toegestaan (maar niet vereist) om dezelfde gemachtigde instantie te retourneren. De term semantisch identiek wordt hier gebruikt om te betekenen dat de uitvoering van de anonieme functies in alle gevallen dezelfde effecten zal opleveren op basis van dezelfde argumenten. Met deze regel kan code, zoals het volgende, worden geoptimaliseerd.
delegate double Function(double x);
class Test
{
static double[] Apply(double[] a, Function f)
{
double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++)
{
result[i] = f(a[i]);
}
return result;
}
static void F(double[] a, double[] b)
{
a = Apply(a, (double x) => Math.Sin(x));
b = Apply(b, (double y) => Math.Sin(y));
...
}
}
Aangezien de twee anonieme functiedelegen dezelfde (lege) set vastgelegde buitenste variabelen hebben en omdat de anonieme functies semantisch identiek zijn, mag een compiler de gedelegeerden naar dezelfde doelmethode laten verwijzen. Inderdaad, een compiler mag hetzelfde delegate-object retourneren van beide anonieme functie-expressies.
10.7.3 Evaluatie van lambda-expressieconversies naar expressiestructuurtypen
De conversie van een lambda-expressie naar een expressiestructuurtype produceert een expressiestructuur (§8.6). De evaluatie van de lambda-expressieconversie produceert een objectstructuur die de structuur van de lambda-expressie zelf vertegenwoordigt.
Niet elke lambda-expressie kan worden geconverteerd naar expressiestructuurtypen. De conversie naar een compatibel type gemachtigde bestaat altijd, maar kan mislukken tijdens het compileren om door de implementatie gedefinieerde redenen.
Opmerking: Veelvoorkomende redenen waarom een lambda-expressie niet kan worden geconverteerd naar een expressiestructuurtype, zijn onder andere:
- Het heeft een bloktekst
- Het heeft de
asyncwijzigingsfunctie- Deze bevat een toewijzingsoperator
- Deze bevat een uitvoer- of verwijzingsparameter
- Deze bevat een dynamisch gebonden expressie
eindnotitie
10.8 Groepsconversies
Er bestaat een impliciete conversie van een methodegroep (§12.2) naar een compatibel gemachtigdetype (§21.4). Als D een gemachtigde is en E een expressie is die is geclassificeerd als een methodegroep, is dan D alleen compatibel met E als en alleen als E er ten minste één methode bevat die van toepassing is in de normale vorm (§12.6.4.2) op een lijst met argumenten (§12.6.2) met typen en modifiers die overeenkomen met de parametertypen en modifiers van D, zoals beschreven in het volgende.
De compilatietijdtoepassing van de conversie van een methodegroep E naar een gedelegeerde type D wordt in het volgende beschreven.
- Er wordt één methode
Mgeselecteerd die overeenkomt met een methode-aanroep (§12.8.10.2) van het formulierE(A), met de volgende wijzigingen:- De argumentenlijst
Ais een lijst met expressies, die elk zijn geclassificeerd als een variabele en met het type en de wijzigingsfunctie (in,outofref) van de bijbehorende parameter in het parameter_list vanD, met uitzondering van parameters van het typedynamic, waarbij de bijbehorende expressie het typeobjectheeft in plaats vandynamic. - De kandidaatmethoden die worden beschouwd, zijn alleen methoden die van toepassing zijn in hun normale vorm en laten geen optionele parameters weg (§12.6.4.2). Kandidaatmethoden worden dus genegeerd als ze alleen van toepassing zijn in hun uitgevouwen vorm, of als een of meer van hun optionele parameters geen bijbehorende parameter hebben.
D
- De argumentenlijst
- Een conversie wordt beschouwd als het algoritme van §12.8.10.2 één beste methode
Mproduceert die compatibel is (§21.4) metD. - Als de geselecteerde methode
Meen exemplaarmethode is, bepaalt de exemplaarexpressie die isEgekoppeld aan het doelobject van de gemachtigde. - Als de geselecteerde methode een uitbreidingsmethode
Mis die wordt aangeduid met behulp van lidtoegang voor een exemplaarexpressie, bepaalt die instantie-expressie het doelobject van de gemachtigde. - Het resultaat van de conversie is een waarde van het type
D, namelijk een gemachtigde die verwijst naar de geselecteerde methode en het doelobject.
Voorbeeld: Hieronder ziet u groepsconversies van methoden:
delegate string D1(object o); delegate object D2(string s); delegate object D3(); delegate string D4(object o, params object[] a); delegate string D5(int i); class Test { static string F(object o) {...} static void G() { D1 d1 = F; // Ok D2 d2 = F; // Ok D3 d3 = F; // Error – not applicable D4 d4 = F; // Error – not applicable in normal form D5 d5 = F; // Error – applicable but not compatible } }De toewijzing om
d1impliciet de methodegroepFte converteren naar een waarde van het typeD1.De toewijzing om te
d2laten zien hoe het mogelijk is om een gemachtigde te maken voor een methode met minder afgeleide parametertypen (contravariant) en een meer afgeleid (covariant) retourtype.De toewijzing om te
d3laten zien hoe er geen conversie bestaat als de methode niet van toepassing is.De toewijzing die laat
d4zien hoe de methode van toepassing moet zijn in de normale vorm.De toewijzing om te
d5laten zien hoe parameter- en retourtypen van de gemachtigde en methode alleen mogen verschillen voor referentietypen.eindvoorbeeld
Net als bij alle andere impliciete en expliciete conversies kan de cast-operator worden gebruikt om expliciet een bepaalde conversie uit te voeren.
Voorbeeld: Het voorbeeld
object obj = new EventHandler(myDialog.OkClick);kan in plaats daarvan worden geschreven
object obj = (EventHandler)myDialog.OkClick;eindvoorbeeld
Een methodegroepconversie kan verwijzen naar een algemene methode, hetzij door expliciet typeargumenten op te geven binnen Eof via typedeductie (§12.6.3). Als typedeductie wordt gebruikt, worden de parametertypen van de gemachtigde gebruikt als argumenttypen in het deductieproces. Het retourtype van de gemachtigde wordt niet gebruikt voor deductie. Of de typeargumenten worden opgegeven of afgeleid, ze maken deel uit van het conversieproces van de methodegroep; dit zijn de typeargumenten die worden gebruikt om de doelmethode aan te roepen wanneer de resulterende gemachtigde wordt aangeroepen.
Voorbeeld:
delegate int D(string s, int i); delegate int E(); class X { public static T F<T>(string s, T t) {...} public static T G<T>() {...} static void Main() { D d1 = F<int>; // Ok, type argument given explicitly D d2 = F; // Ok, int inferred as type argument E e1 = G<int>; // Ok, type argument given explicitly E e2 = G; // Error, cannot infer from return type } }eindvoorbeeld
Methodegroepen kunnen invloed hebben op overbelastingsresolutie en deelnemen aan typedeductie. Zie §12.6 voor meer informatie.
De runtime-evaluatie van een methodegroepconversie gaat als volgt:
- Als de methode die tijdens het compileren is geselecteerd, een exemplaarmethode is of een extensiemethode is die als instantiemethode wordt geopend, wordt het doelobject van de gemachtigde bepaald op basis van de instantie-expressie die is gekoppeld aan
E:- De exemplaarexpressie wordt geëvalueerd. Als deze evaluatie een uitzondering veroorzaakt, worden er geen verdere stappen uitgevoerd.
- Als de exemplaarexpressie van een reference_type is, wordt de waarde die wordt berekend door de exemplaarexpressie het doelobject. Als de geselecteerde methode een exemplaarmethode is en het doelobject is
null, wordt er eenSystem.NullReferenceExceptiongegenereerd en worden er geen verdere stappen uitgevoerd. - Als de exemplaarexpressie van een value_type is, wordt een boksbewerking (§10.2.9) uitgevoerd om de waarde te converteren naar een object en wordt dit object het doelobject.
- Anders maakt de geselecteerde methode deel uit van een statische methode-aanroep en is
nullhet doelobject van de gemachtigde. - Een gemachtigde instantie van het type gemachtigde
Dwordt als volgt verkregen met een verwijzing naar de methode die tijdens het compileren is bepaald en een verwijzing naar het hierboven berekende doelobject:- De conversie is toegestaan (maar niet vereist) om een bestaand gemachtigde exemplaar te gebruiken dat deze verwijzingen al bevat.
- Als een bestaand exemplaar niet opnieuw is gebruikt, wordt er een nieuwe gemaakt (§21.5). Als er onvoldoende geheugen beschikbaar is om het nieuwe exemplaar toe te wijzen, wordt er een
System.OutOfMemoryExceptiongegenereerd. Anders wordt het exemplaar geïnitialiseerd met de opgegeven verwijzingen.
ECMA C# draft specification