Hoppa till innehåll

Datatyper och typomvandling

↑

Exemplen är oberoende C#-utdrag för moderna .NET-konsolprojekt, om inget annat anges. Klassdeklarationer och toppnivåkod kan placeras i samma Program.cs-fil, med toppnivåkoden först.

En datatyp avgör vilka värden som kan lagras och vilka operationer som går att göra. Omvandlingar kan förlora information, så välj typ med omsorg.

int lagrar 32-bitars heltal med tecken och long större heltal. float och double är binära flyttal som kan avrundas. decimal passar ofta bättre för ekonomiska decimalvärden. bool lagrar true eller false, och char en UTF-16-kodenhet.

Example.cs
int lives = 3;
long totalScore = 2_000_000_000L;
float speed = 4.5f;
double precision = 0.1;
decimal price = 19.95m;
bool active = true;
char grade = 'A';

En implicit konvertering kan göras utan en uttrycklig cast, till exempel från int till long. En explicit cast kan kasta bort decimaler eller ge overflow. Använd checked när overflow måste upptäckas.

Example.cs
int count = 12;
long exact = count; // implicit
int truncated = (int)8.9; // 8
Console.WriteLine($"{exact}, {truncated}");

int.Parse kastar undantag om texten är felaktig. För inmatning och osäkra värden passar int.TryParse bättre. Hantera misslyckad konvertering tydligt.

Example.cs
string input = "42";
if (int.TryParse(input, out int value))
Console.WriteLine(value * 2);
else
Console.WriteLine("Not an integer");

Fördjupning: förstå vad som lagras och kan gå förlorat

Section titled “Fördjupning: förstå vad som lagras och kan gå förlorat”

En int-variabel innehåller direkt ett heltalsvärde. En variabel med klasstyp innehåller normalt en referens till ett objekt. När du tilldelar ett heltal till en annan variabel kopieras värdet. När du kopierar en klassreferens kan båda variablerna peka på samma objekt. string är en referenstyp, men strängar är oföränderliga: ToUpper() ger en ny sträng och ändrar inte den ursprungliga.

Program.cs
int first = 10;
int second = first;
second = 20;
Console.WriteLine(first); // 10
var a = new List<int> { 1 };
var b = a;
b.Add(2);
Console.WriteLine(a.Count); // 2: samma lista

string? name anger att null tillåts när analys av nullable-referenser är aktiverad. Kontrollera null innan du läser en referens som kan saknas. Även värdetyper kan göras nullable, exempelvis int?.

float och double approximerar många decimalbråk eftersom de lagras som binära flyttal. De passar fysik och mätningar, men 0.1 + 0.2 behöver inte bli exakt 0.3 för double. Jämför därför ofta med en tolerans som passar problemet i stället för exakt likhet. decimal kan representera många vanliga decimala penningbelopp exakt, men avrundningsregler behöver fortfarande väljas.

En int ryms alltid i long. En long kan vara för stor för int, och en konvertering från double till int tappar decimaldelen. checked gör att heltalsöverflöd i kontrollerade sammanhang leder till undantag; unchecked tillåter visst omslagsbeteende. En cast garanterar inte att resultatet är säkert.

Program.cs
long large = 3_000_000_000;
try
{
int narrowed = checked((int)large);
Console.WriteLine(narrowed);
}
catch (OverflowException)
{
Console.WriteLine("Number is too large for int");
}

Använd int för vanliga räknare och index, long när större heltal krävs, bool för villkor, decimal för pengar och exempelvis DateTimeOffset för tidpunkter. I Unity är float vanligt för positioner och rörelse eftersom många vektor- och fysik-API:er använder enkel precision. Undvik onödiga konverteringar mellan float och double i varje bildruta.

Använd heltal för antal och index, double för många beräkningar och decimal när decimal precision är viktig.

Jämför inte beräknade flyttal med == utan eftertanke. En stor long kan förlora information vid konvertering till int.

Ta emot ett tal som text och skriv ut antingen dubbla värdet eller ett tydligt felmeddelande.

Visa ett lösningsförslag

Använd int.TryParse(text, out int number) och hantera grenen där resultatet är false.