Language: EN

csharp-conversion-tipos-cast

Convert between types with Cast in C#

Type conversion, also known as casting or coercion, is the process of transforming a value from one data type to another.

This may be necessary when working with different data types and requiring a specific value to be treated as another type.

There are two main types of conversions in C#: implicit conversions and explicit conversions.

Implicit Conversions

Implicit conversions are those that the compiler automatically performs without the need for explicit intervention by the programmer.

This is possible when there is no risk of data loss, or when the target data type is larger than the source data type.

For example, if we have a variable of type int and want to assign its value to a variable of type long, no explicit conversion is necessary, as C# will automatically perform the implicit conversion:

int integerNumber = 10;
long longNumber = integerNumber;

In this case, the integerNumber variable is implicitly converted to long and assigned to the longNumber variable.

Explicit Conversions

Explicit conversion, also known as casting, is used when a data conversion cannot be performed automatically by the compiler. This may occur when there is a risk of data loss.

To perform an explicit conversion in C#, it is necessary to use the casting operator

(dataType)object

Where

  • dataType is the target data type
  • object is the object to be converted.

For example, if we have a variable of type double and want to convert it to type int, we need to perform an explicit conversion:

double decimalNumber = 3.14;
int integerNumber = (int)decimalNumber;

In this case, we use the casting (int) to convert the decimalNumber variable to int. It is important to note that, in this example, the decimal part of the original number will be lost.

Conversion between reference types

It is also possible to perform conversions between reference types, such as classes and interfaces. These conversions can be more complex and require a good understanding of type hierarchy and inheritance.

Casting between different reference types should be done carefully, and only if we are sure that the conversion is valid.

If the conversion is not valid, it will cause a runtime error 💥

Conversion from base classes to derived classes

public class Animal
{
    public void MakeSound()
    {
        Console.WriteLine("Animal sound");
    }
}

public class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine("Woof!");
    }
}

public class Program
{
    public static void Main()
    {
        Animal myAnimal = new Dog(); // Implicit conversion from Dog to Animal
        Dog myDog = (Dog)myAnimal; // Explicit conversion from Animal to Dog

        myDog.Bark(); // Output: Woof!
    }
}

In this example, myAnimal is implicitly converted to Animal when instantiated as Dog. Then, an explicit conversion is performed from Animal to Dog to access the specific method of the derived class Dog.

Using is and as operators

The is and as operators facilitate safe checking and conversion between reference types.

is operator

The is operator is used to check if an object is of a specific type.

object obj = "Hello, World!";
if (obj is string)
{
    Console.WriteLine("obj is a string");
}

as operator

The as operator attempts to convert an object to a specified type and returns null if the conversion fails.

object obj = "Hello, World!";
string text = obj as string;

if (text != null)
{
    Console.WriteLine("The conversion was successful: " + text);
}
else
{
    Console.WriteLine("The conversion failed");
}

User-defined conversion

C# allows defining custom conversions between types by overloading implicit and explicit conversion operators.

User-defined implicit conversion

public class Celsius
{
    public float Degrees { get; set; }

    public Celsius(float degrees)
    {
        Degrees = degrees;
    }

    public static implicit operator Fahrenheit(Celsius c)
    {
        return new Fahrenheit((c.Degrees * 9 / 5) + 32);
    }
}

public class Fahrenheit
{
    public float Degrees { get; set; }

    public Fahrenheit(float degrees)
    {
        Degrees = degrees;
    }
}

public class Program
{
    public static void Main()
    {
        Celsius celsius = new Celsius(25);
        Fahrenheit fahrenheit = celsius; // Implicit conversion
        Console.WriteLine(fahrenheit.Degrees); // Output: 77
    }
}

User-defined explicit conversion

public class Celsius
{
    public float Degrees { get; set; }

    public Celsius(float degrees)
    {
        Degrees = degrees;
    }

    public static explicit operator Fahrenheit(Celsius c)
    {
        return new Fahrenheit((c.Degrees * 9 / 5) + 32);
    }
}

public class Fahrenheit
{
    public float Degrees { get; set; }

    public Fahrenheit(float degrees)
    {
        Degrees = degrees;
    }
}

public class Program
{
    public static void Main()
    {
        Celsius celsius = new Celsius(25);
        Fahrenheit fahrenheit = (Fahrenheit)celsius; // Explicit conversion
        Console.WriteLine(fahrenheit.Degrees); // Output: 77
    }
}

Practical examples

Let’s see some examples of conversions between basic types.

Conversion from int to float

int integerNumber = 100;
float floatNumber = integerNumber; // Implicit conversion
Console.WriteLine(floatNumber); // Output: 100

Conversion from double to int

double doubleNumber = 123.456;
int integerNumber = (int)doubleNumber; // Explicit conversion
Console.WriteLine(integerNumber); // Output: 123 (decimal part is lost)

Conversion from char to int

char letter = 'A';
int asciiCode = (int)letter; // Explicit conversion
Console.WriteLine(asciiCode); // Output: 65 (ASCII code of 'A')