Skip to content

Data types and type conversion

↑

Examples are independent C# snippets for modern .NET console projects unless noted otherwise. Class declarations and top-level code can live in Program.cs when top-level statements come first.

A type determines which values a variable can hold and which operations are legal. Conversion is not always lossless, so choose types deliberately.

int stores 32-bit signed integers; long stores larger ones. float and double are binary floating-point types and may have rounding error. decimal is often preferable for base-10 financial values. bool stores true or false, and char stores a UTF-16 code unit.

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';

An implicit conversion is available when the compiler permits it, for example from int to long. Explicit casts may discard fractional parts or overflow. Use checked where overflow must be detected.

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

int.Parse throws when input is invalid. Prefer int.TryParse for user input and other values that might be malformed. A failed conversion should produce a clear result rather than an unhandled exception.

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

Deep dive: understand what is stored and what is lost

Section titled “Deep dive: understand what is stored and what is lost”

An int variable directly holds an integer value. A variable of a class type normally holds a reference to an object. Assigning one integer variable to another copies the value; assigning a class reference copies the reference, so both variables can reach the same object. string is a reference type, but strings are immutable: operations such as ToUpper() produce a new string instead of changing the original.

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: shared list object

string? name expresses that null is permitted when nullable reference analysis is enabled. Checking for null prevents dereferencing a missing object. Nullable value types such as int? can store an integer or no value.

Binary floating-point and decimal arithmetic

Section titled “Binary floating-point and decimal arithmetic”

float and double approximate many decimal fractions because they store binary floating-point numbers. They are useful for physics and measurements, but 0.1 + 0.2 may not be exactly 0.3 as a double. Use tolerances appropriate to your domain, rather than exact equality after complicated calculations. decimal represents many base-10 financial amounts exactly, although operations and rounding still need deliberate rules.

Widening, narrowing, and checked arithmetic

Section titled “Widening, narrowing, and checked arithmetic”

Converting int to long always preserves a 32-bit integer. Converting long to int can overflow; converting double to int discards the fractional part. checked makes overflowing integral conversions and arithmetic throw in checked contexts; unchecked allows specified wrapping behavior. Do not assume a cast means a safe conversion.

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");
}

Use int for most small counts and indexes, long for larger counts, bool for conditions, decimal for money, and types such as DateTimeOffset for points in time. In Unity, float is common for positions and movement because Unity’s vector and physics APIs frequently use single precision. Avoid unnecessarily converting between float and double every frame.

Use integers for counts and indexes, double for many scientific calculations, and decimal when decimal financial precision matters.

Do not use == blindly for computed floating-point results. Converting a large long into int may lose data.

Accept a number as text and print either its doubled value or a helpful error.

Reveal a solution

Use int.TryParse(text, out int number) and handle the false branch.