Converting Data Types in C#

C# converts a smaller type to a larger one for you; anything else you convert yourself, with a cast, the Convert class, or Parse for text.

Apprentice · C# · Updated

After this lesson you can

  • Convert between numeric types with a cast or the Convert class
  • Turn text into a number with Parse or TryParse

Key takeaways

  • C# converts for you only when the new type can hold every value, such as an int into a long or a double.
  • A cast such as (int)hours cuts off the decimals; Convert.ToInt32 rounds.
  • A cast is a promise that the value fits. If it doesn't, you get a wrong number, not an error.
  • int.Parse and decimal.Parse turn text into a number; TryParse does it safely when the text might not be a number.

Values often arrive as one type when you need another: a whole number you need to multiply by a price, or a number a user typed, which arrives as text. Converting between types is part of almost every calculation.

Conversions C# makes for you

C# converts a value automatically when the new type can hold it: when a smaller type fits into a larger one.

string name = "Gary";
int age = 27;

// Text plus a number: C# turns the number into text and joins them
Console.WriteLine(name + " is " + age);

int gallonsInFishTank = 55;
long gallonsInLake = 3000000000L;

// An int fits in a long, so gallonsInFishTank becomes a long before adding
long totalGallons = gallonsInFishTank + gallonsInLake;
Console.WriteLine(totalGallons);
Gary is 27
3000000055

These conversions always work, so C# makes them for you:

  • byte into short, int or long
  • short into int or long
  • int into long, double or decimal
  • long into double or decimal
  • float into double

(One small catch: a long bigger than about 9 quadrillion can lose its last few digits when it becomes a double. You won't meet numbers that big in this course.)

The other direction is not automatic. Even when the value is small, C# will not put a long into an int, because another value might not fit:

long bigAge = 18;

// This line does not compile: a long might not fit in an int
int age = bigAge;

The compiler stops with an error like Cannot implicitly convert type 'long' to 'int'. When you know the value fits, you convert it yourself.

Casting

A cast tells C# which type you want. Write the type in parentheses in front of the value:

long bigAge = 18;
int age = (int)bigAge;

double price = 7.99;
int wholeDollars = (int)price;

Console.WriteLine(age);
Console.WriteLine(wholeDollars);
18
7

Casting a double to an int doesn't round. It cuts off everything after the decimal point, so 7.99 becomes 7.

A cast is a promise that the value fits. If it doesn't, C# keeps the promise anyway, and you get a wrong answer with no warning:

long manyGallons = 3000000000L;
int gallons = (int)manyGallons;

Console.WriteLine(gallons);
-1294967296

3 billion is bigger than the largest int (about 2.1 billion), so the number wrapped around past the top and came back negative. Cast only when you are sure the value fits.

The Convert class

The Convert class has a method for each type, such as Convert.ToInt32 for int (32 is how many bits an int uses) and Convert.ToDecimal. Unlike a cast, it rounds to the nearest whole number instead of cutting off:

double hoursWorked = 7.6;

int byCast = (int)hoursWorked;
int byConvert = Convert.ToInt32(hoursWorked);

Console.WriteLine("Cast:    " + byCast);
Console.WriteLine("Convert: " + byConvert);
Cast:    7
Convert: 8

Convert also refuses to wrap around. A value too big for the type stops the program with an error, which is better than a wrong answer you might not notice.

double and decimal don't mix

double and decimal both hold decimals, but they store them differently, so C# won't calculate with one of each. Convert one first:

double areaInSquareFeet = 128.5;
decimal pricePerSquareFoot = 5.25m;

// pricePerSquareFoot * areaInSquareFeet would not compile
decimal totalCost = pricePerSquareFoot * (decimal)areaInSquareFeet;

Console.WriteLine(totalCost);
674.625

Turning text into a number

Text that looks like a number is still text. Adding to it joins, it doesn't add:

string age = "25";
Console.WriteLine(age + 1);
251

To calculate with it, turn the text into a number. Each number type has a Parse method:

string ageText = "25";
int age = int.Parse(ageText);
Console.WriteLine(age + 1);

string priceText = "15.50";
decimal price = decimal.Parse(priceText);
decimal discount = price * 0.1m;
Console.WriteLine("The 10% discount is " + discount);
26
The 10% discount is 1.550

Parse stops the program with an error when the text isn't a number, such as "twenty". When the text comes from a person, who can type anything, use TryParse. It returns true or false instead of stopping, and puts the number in a variable you name after out:

string typed = "twenty";

bool isNumber = int.TryParse(typed, out int quantity);

Console.WriteLine("Is it a number? " + isNumber);
Console.WriteLine("Quantity: " + quantity);
Is it a number? False
Quantity: 0

When the text isn't a number, quantity is 0 and isNumber is false, so your program can ask again. You will do exactly that once you can make decisions with if.

Turning a number into text

Every value has a ToString method, which gives its value as text. You have been using it without seeing it: joining a number to text with + calls ToString for you.

int score = 42;
string scoreText = score.ToString();

Console.WriteLine(scoreText + " points");
42 points

Check yourself

2 questions to try on the lesson page.

So what

C# converts for you only when the new type can hold the value. Everywhere else, you choose: a cast when you know the value fits, Convert when you want rounding and a safety check, and Parse or TryParse when the value arrives as text.

Key terms

Cheat sheets