Dela via


Konvertering av gjutning och typ (programmeringsguide för C#)

Eftersom C# skrivs statiskt vid kompileringstillfället kan den inte deklareras igen eller tilldelas ett värde av en annan typ när en variabel har deklarerats, såvida inte den typen implicit kan konverteras till variabelns typ. Det string går till exempel inte att implicit konvertera till int. När du har deklarerat i som en intkan du därför inte tilldela strängen "Hello" till den, som följande kod visar:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

Du kan dock ibland behöva kopiera ett värde till en variabel eller metodparameter av en annan typ. Du kan till exempel ha en heltalsvariabel som du behöver skicka till en metod vars parameter skrivs som double. Eller så kan du behöva tilldela en klassvariabel till en variabel av en gränssnittstyp. Den här typen av åtgärder kallas typkonverteringar. I C# kan du utföra följande typer av konverteringar:

  • Implicita konverteringar: Ingen särskild syntax krävs eftersom konverteringen alltid lyckas och inga data går förlorade. Exempel är konverteringar från mindre till större integraltyper, konverteringar från härledda klasser till basklasser och omfångskonverteringar.

  • Explicita konverteringar (casts): Explicita konverteringar kräver ett cast-uttryck. Casting krävs när information kan gå förlorad i konverteringen, eller när konverteringen kanske inte lyckas av andra skäl. Vanliga exempel är numerisk konvertering till en typ som har mindre precision eller ett mindre intervall och konvertering av en basklassinstans till en härledd klass.

  • Användardefinierade konverteringar: Användardefinierade konverteringar använder särskilda metoder som du kan definiera för att aktivera explicita och implicita konverteringar mellan anpassade typer som inte har en basklass-härledd klassrelation. Mer information finns i Användardefinierade konverteringsoperatorer.

  • Konverteringar med hjälpklasser: Om du vill konvertera mellan icke-kompatibla typer, till exempel heltal och System.DateTime objekt eller hexadecimala strängar och bytematriser, kan du använda System.BitConverter klassen, System.Convert klassen och Parse metoderna för de inbyggda numeriska typerna, till exempel Int32.Parse. Mer information finns i följande artiklar:

  • Konvertera en bytematris till en int-

  • Konvertera en sträng till ett tal

  • Konvertera mellan hexadecimala strängar och numeriska typer

Implicita konverteringar

För inbyggda numeriska typer kan en implicit konvertering göras när värdet som ska lagras får plats i variabeln utan att trunkeras eller avrundas. För integraltyper innebär den här begränsningen att källtypens intervall är en lämplig delmängd av intervallet för måltypen. En variabel av typen long (64-bitars heltal) kan till exempel lagra valfritt värde som ett int (32-bitars heltal) kan lagra. I följande exempel konverterar kompilatorn implicit värdet num på höger sida till typen long innan det tilldelas bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

En fullständig lista över alla implicita numeriska konverteringar finns i avsnittet Implicita numeriska konverteringar i artikeln Inbyggda numeriska konverteringar .

För referenstyper finns alltid en implicit konvertering från en klass till någon av dess direkta eller indirekta basklasser eller gränssnitt. Ingen särskild syntax krävs eftersom en härledd klass alltid innehåller alla medlemmar i en basklass.

Derived d = new Derived();

// Always OK.
Base b = d;

Explicita konverteringar

Men om en konvertering inte kan göras utan risk för att förlora information, kräver kompilatorn att du utför en explicit konvertering, som kallas cast. En rollbesättning är ett sätt att explicit göra konverteringen. Det indikerar att du är medveten om att dataförlust kan inträffa, eller att typkonverteringen kan misslyckas under körning. Om du vill utföra en cast anger du måltypen inom parenteser innan det uttryck som du vill konvertera. Följande program omvandlar en double till en int. Programmet kompileras inte utan typomvandlingen.

double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
Console.WriteLine(a);
// Output: 1234

En fullständig lista över explicita numeriska konverteringar som stöds finns i avsnittet Explicita numeriska konverteringari artikeln Inbyggda numeriska konverteringar .

För referenstyper krävs en explicit gjutning om du behöver konvertera från en bastyp till en härledd typ:

En typkonvertering mellan referenstyper ändrar inte körtidstypen för det underliggande objektet; den ändrar bara typen av värde som används som referens till det objektet. Mer information finns i Polymorfism.

Typkonverteringsfel vid körning

I vissa referenstypkonverteringar kan kompilatorn inte avgöra om en cast är giltig. Det är möjligt att en gjuten åtgärd som kompileras korrekt misslyckas vid körning. Som du ser i följande exempel leder en typgjutning som misslyckas vid körningen till att en InvalidCastException genereras.

Animal a = new Mammal();
Reptile r = (Reptile)a; // InvalidCastException at run time

Att uttryckligen konvertera argumentet a till en Reptile innebär ett farligt antagande. Det är säkrare att inte göra antaganden, utan i stället kontrollera typen. C# tillhandahåller operatorn is så att du kan testa kompatibiliteten innan du faktiskt utför en cast. Mer information finns i Så här typkonverterar du säkert med mönstermatchning och operatorerna *as* och *is*.

Språkspecifikation för C#

Mer information finns i avsnittet Konverteringar i C#-språkspecifikationen.

Se även