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
intinto alongor adouble. - A cast such as
(int)hourscuts off the decimals;Convert.ToInt32rounds. - A cast is a promise that the value fits. If it doesn't, you get a wrong number, not an error.
int.Parseanddecimal.Parseturn text into a number;TryParsedoes 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:
byteintoshort,intorlongshortintointorlongintintolong,doubleordecimallongintodoubleordecimalfloatintodouble
(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.