Skip to main content

C# Type Conversion

Type conversion is the process of changing a value from one data type to another. In C#, this is a common operation that you'll need to understand to build effective applications. Converting between types allows your program to work with different kinds of data in a flexible way.

Introduction to Type Conversion​

When programming in C#, you'll often need to convert data from one type to another. For example, you might need to:

  • Convert a string input from a user to a number for calculations
  • Change a decimal value to an integer for counting
  • Convert a number to a string for display purposes

C# provides several ways to convert between types, each with its own purpose and considerations:

  1. Implicit conversion - Happens automatically when no data loss is possible
  2. Explicit conversion (casting) - Requires explicit code when data loss might occur
  3. Helper class methods - Using Convert class for more flexibility
  4. Parsing methods - Converting strings to other data types

Let's explore each of these approaches in detail.

Implicit Type Conversion​

Implicit conversion happens automatically when there's no risk of data loss. C# allows you to assign a smaller type to a larger type without any special syntax.

Example of Implicit Conversion:​

csharp
// Implicit conversion from int to double
int myInt = 42;
double myDouble = myInt; // No explicit conversion required

Console.WriteLine($"Integer value: {myInt}");
Console.WriteLine($"Double value: {myDouble}");

Output:

Integer value: 42
Double value: 42

Common implicit conversions include:

  • byte → short → int → long → float → double → decimal
  • char → int
  • Any type → string (using string concatenation or interpolation)

This works because the destination type can always accommodate all possible values of the source type. For instance, any integer can be represented as a double without losing information.

Explicit Type Conversion (Casting)​

When conversion might result in data loss (like converting from a larger type to a smaller one), you must use explicit conversion or "casting" to tell the compiler that you're aware of potential data loss.

Example of Explicit Conversion:​

csharp
// Explicit conversion (casting) from double to int
double myDouble = 42.75;
int myInt = (int)myDouble; // Explicit cast, decimal part will be truncated

Console.WriteLine($"Double value: {myDouble}");
Console.WriteLine($"Integer value after casting: {myInt}");

Output:

Double value: 42.75
Integer value after casting: 42

Notice that the decimal part is truncated (not rounded) when casting from double to int. This is a potential data loss that you need to be aware of.

Using the Convert Class​

The Convert class in C# provides methods for converting between various base types. These methods generally handle special cases like null values better than casting.

Example Using the Convert Class:​

csharp
// Using Convert class methods
string numberString = "123";
int convertedInt = Convert.ToInt32(numberString);
double convertedDouble = Convert.ToDouble(numberString);
bool convertedBool = Convert.ToBoolean(1); // Non-zero becomes true

Console.WriteLine($"Converted int: {convertedInt}");
Console.WriteLine($"Converted double: {convertedDouble}");
Console.WriteLine($"Converted bool: {convertedBool}");

// Convert also handles null values
string nullString = null;
int convertedFromNull = Convert.ToInt32(nullString); // Returns 0 for null
Console.WriteLine($"Null string converted to int: {convertedFromNull}");

Output:

Converted int: 123
Converted double: 123
Converted bool: True
Null string converted to int: 0

The Convert class has methods like ToInt32(), ToDouble(), ToString(), and many others for different conversions.

Parsing Methods​

For converting strings to numeric types, C# provides specific parsing methods. These are often preferred for string-to-numeric conversions.

Example of Parsing Methods:​

csharp
// String to number conversion with parsing
string intString = "456";
string doubleString = "123.45";

int parsedInt = int.Parse(intString);
double parsedDouble = double.Parse(doubleString);

Console.WriteLine($"Parsed int: {parsedInt}");
Console.WriteLine($"Parsed double: {parsedDouble}");

Output:

Parsed int: 456
Parsed double: 123.45

TryParse for Safe Conversions​

When working with user input or data from external sources, it's safer to use TryParse methods which won't throw exceptions on invalid input.

Example of TryParse:​

csharp
// TryParse provides safe conversion without exceptions
string validNumber = "789";
string invalidNumber = "abc";

if (int.TryParse(validNumber, out int number1))
{
Console.WriteLine($"Successfully parsed: {number1}");
}
else
{
Console.WriteLine("Parsing failed");
}

if (int.TryParse(invalidNumber, out int number2))
{
Console.WriteLine($"Successfully parsed: {number2}");
}
else
{
Console.WriteLine("Parsing failed");
}

Output:

Successfully parsed: 789
Parsing failed

TryParse returns true if the conversion was successful and false otherwise. The parsed value is assigned to the out parameter if successful.

Handling Conversion Errors​

Type conversion can lead to exceptions if not handled properly. Here are common exceptions and how to handle them:

Example of Handling Conversion Errors:​

csharp
// Safe conversion with exception handling
try
{
string overflow = "2147483648"; // Value is too large for Int32
int willOverflow = int.Parse(overflow);
Console.WriteLine($"Converted value: {willOverflow}");
}
catch (OverflowException)
{
Console.WriteLine("Error: The number is too large for an integer");
}
catch (FormatException)
{
Console.WriteLine("Error: The string does not represent a number");
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error: {ex.Message}");
}

Output:

Error: The number is too large for an integer

Real-world Applications​

Let's look at some practical examples of type conversion in real applications:

Example 1: Processing User Input​

csharp
// A simple calculator that takes user input
Console.Write("Enter first number: ");
string input1 = Console.ReadLine();

Console.Write("Enter second number: ");
string input2 = Console.ReadLine();

if (double.TryParse(input1, out double num1) && double.TryParse(input2, out double num2))
{
double sum = num1 + num2;
Console.WriteLine($"Sum: {sum}");

// Converting back to string with specific format
string formattedResult = sum.ToString("0.00");
Console.WriteLine($"Formatted result: {formattedResult}");
}
else
{
Console.WriteLine("Invalid input. Please enter valid numbers.");
}

Example 2: Working with Configuration Values​

csharp
// Simulate reading app settings
Dictionary<string, string> appSettings = new Dictionary<string, string>
{
{ "MaxRetries", "3" },
{ "Timeout", "30.5" },
{ "IsEnabled", "true" }
};

// Convert settings to appropriate types
if (int.TryParse(appSettings["MaxRetries"], out int maxRetries))
{
Console.WriteLine($"Max retries: {maxRetries}");
}

if (double.TryParse(appSettings["Timeout"], out double timeout))
{
Console.WriteLine($"Timeout: {timeout} seconds");
}

if (bool.TryParse(appSettings["IsEnabled"], out bool isEnabled))
{
Console.WriteLine($"Is enabled: {isEnabled}");
}

Output:

Max retries: 3
Timeout: 30.5 seconds
Is enabled: true

Boxing and Unboxing​

Boxing and unboxing are special forms of type conversion between value types and reference types.

Example of Boxing and Unboxing:​

csharp
// Boxing: converting a value type to object (reference type)
int number = 42;
object boxedNumber = number; // Boxing

// Unboxing: converting the object back to value type
int unboxedNumber = (int)boxedNumber; // Unboxing

Console.WriteLine($"Original: {number}");
Console.WriteLine($"After boxing and unboxing: {unboxedNumber}");

Output:

Original: 42
After boxing and unboxing: 42

Boxing is implicit, but unboxing requires an explicit cast. Boxing and unboxing have performance implications as they involve memory allocation and type checking.

Custom Type Conversions​

For your own classes, you can define custom type conversions using conversion operators.

Example of Custom Type Conversion:​

csharp
public class Temperature
{
public double Celsius { get; }

public Temperature(double celsius)
{
Celsius = celsius;
}

// Implicit conversion from double to Temperature
public static implicit operator Temperature(double celsius)
{
return new Temperature(celsius);
}

// Explicit conversion from Temperature to double (returns Celsius)
public static explicit operator double(Temperature temperature)
{
return temperature.Celsius;
}
}

// Usage
Temperature temp1 = new Temperature(25.0);
Temperature temp2 = 30.0; // Implicit conversion from double

double celsius = (double)temp1; // Explicit conversion to double

Console.WriteLine($"Temperature 1: {temp1.Celsius}°C");
Console.WriteLine($"Temperature 2: {temp2.Celsius}°C");
Console.WriteLine($"Celsius value: {celsius}°C");

Summary​

Type conversion is an essential concept in C# programming. We've covered:

  • Implicit conversion: Automatic conversion when no data loss is possible
  • Explicit conversion (casting): Manual conversion using (type) syntax
  • Convert class methods: Versatile conversion including handling nulls
  • Parsing methods: Converting strings to other data types
  • TryParse methods: Safe conversion that handles errors gracefully
  • Exception handling: Dealing with conversion errors
  • Boxing and unboxing: Converting between value and reference types
  • Custom type conversions: Creating conversions for your own classes

Understanding these concepts will help you write more robust and flexible C# code.

Exercises​

  1. Write a program that converts user-entered temperature from Fahrenheit to Celsius.
  2. Create a function that safely converts strings to decimal for a financial application.
  3. Implement a custom class representing a Distance with conversions between different units (meters, feet, etc.).
  4. Write a program that reads a configuration file with mixed value types and converts each to its appropriate type.
  5. Create a method that can convert between different numeric types while handling potential overflow issues.

Additional Resources​



If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)