Waarom veroorzaakt ?: een conversiefout terwijl if-elst niet?

Als ik enkele wijzigingen in de code aanbreng, gebruik ik de volgende regel:

uint a = b == c ? 0 : 1;

Visual Studio toont me deze fout:

Kan het type ‘int’ niet impliciet converteren naar ‘uint’. Er bestaat een expliciete conversie (mis je een cast?)

Maar als ik de code gebruik:

uint a; 
if (b == c) 
    a = 0; 
else 
    a = 1;

Het werkt correct zonder enige fout of waarschuwing. Waarom?


Antwoord 1, autoriteit 100%

Waarom kan ik uint a = b == c ? 0 : 1;?

Het type van de uitdrukking b == c ? 0 : 1is int. Zoals te zien is in deze tabel, is er geen impliciete conversie van intnaar uint, dus dit is niet toegestaan.

Waarom kan ik a = 0gebruiken?

Omdat er een speciale behandeling is van numerieke typen wanneer de waarde een constante uitdrukking is.

Van sectie 6.1.9 van de C#-specificatie:

  • Een constante expressie van het type int kan worden geconverteerd naar het type sbyte, byte, short, ushort, uint of ulong, op voorwaarde dat de waarde van de constante-expressie binnen het bereik van het bestemmingstype ligt.

  • Een constante expressie van het type long kan worden geconverteerd naar het type ulong, op voorwaarde dat de waarde van de constante expressie niet negatief is.

Zoals aangegeven in het eerste bolletje zijn a = 0en a = 1beide toegestaan ​​omdat 0en 1zijn constante uitdrukkingen en zijn geldige uint-waarden. Waar dit in feite op neerkomt, is dat de compiler tijdens het compileren gemakkelijk kan vaststellen dat deze conversies geldig zijn, en ze dus toestaat.

Overigens, als het b == cdeel van je eerste voorbeeld zou worden gewijzigd in een constante expressie (bijv. true), dan zou de hele voorwaardelijke operator-expressie een constante expressie en de code zou compileren.


Antwoord 2, autoriteit 30%

Alsb==ceen constante expressie was, dan zou de hele voorwaardelijke operator als een constante expressie worden beschouwd en dus de regel die constante expressies van het type intdie moet worden geconverteerd naar andere int-typen, zou van toepassing zijn en zou worden gecompileerd.

Het is duidelijk dat b==cgeen constante uitdrukking is en daarom kan het resultaat van de voorwaardelijke operator pas tijdens runtime bekend zijn en dus de uitzondering die een impliciete conversie van ints naar uint mogelijk maakt (voor constante uitdrukkingen) is niet van toepassing.

In uw if/elsevariant, zijn beidevan de daadwerkelijke toewijzingen constante uitdrukkingen.


Antwoord 3, autoriteit 11%

U moet literalsgebruiken om zorg ervoor dat uw code als volgt correct werkt:

uint a = b == c ? 0U : 1U;

Other episodes