Export (0) Print
Expand All

User-Defined Conversions Tutorial

Visual Studio .NET 2003

This tutorial shows how to define and use conversions to or from classes or structs.

Sample Files

See User-Defined Conversions Sample to download and build the sample files discussed in this tutorial.

Further Reading

Tutorial

C# allows programmers to declare conversions on classes or structs so that classes or structs can be converted to and/or from other classes or structs, or basic types. Conversions are defined like operators and are named for the type to which they convert.

In C#, conversions can be declared either as implicit, which occur automatically when required, or explicit, which require a cast to be called. All conversions must be static, and must either take the type the conversion is defined on, or return that type.

This tutorial introduces two examples. The first example shows how to declare and use conversions, and the second example demonstrates conversions between structs.

Example 1

In this example, a RomanNumeral type is declared, and several conversions to and from it are defined.

// conversion.cs
using System;

struct RomanNumeral
{
    public RomanNumeral(int value) 
    { 
       this.value = value; 
    }
    // Declare a conversion from an int to a RomanNumeral. Note the
    // the use of the operator keyword. This is a conversion 
    // operator named RomanNumeral:
    static public implicit operator RomanNumeral(int value) 
    {
       // Note that because RomanNumeral is declared as a struct, 
       // calling new on the struct merely calls the constructor 
       // rather than allocating an object on the heap:
       return new RomanNumeral(value);
    }
    // Declare an explicit conversion from a RomanNumeral to an int:
    static public explicit operator int(RomanNumeral roman)
    {
       return roman.value;
    }
    // Declare an implicit conversion from a RomanNumeral to 
    // a string:
    static public implicit operator string(RomanNumeral roman)
    {
       return("Conversion not yet implemented");
    }
    private int value;
}

class Test
{
    static public void Main()
    {
        RomanNumeral numeral;

        numeral = 10;

// Call the explicit conversion from numeral to int. Because it is
// an explicit conversion, a cast must be used:
        Console.WriteLine((int)numeral);

// Call the implicit conversion to string. Because there is no
// cast, the implicit conversion to string is the only
// conversion that is considered:
        Console.WriteLine(numeral);
 
// Call the explicit conversion from numeral to int and 
// then the explicit conversion from int to short:
        short s = (short)numeral;

        Console.WriteLine(s);
    }
}

Output

10
Conversion not yet implemented
10

Example 2

This example defines two structs, RomanNumeral and BinaryNumeral, and demonstrates conversions between them.

// structconversion.cs
using System;

struct RomanNumeral
{
    public RomanNumeral(int value) 
    {
        this.value = value; 
    }
    static public implicit operator RomanNumeral(int value)
    {
        return new RomanNumeral(value);
    }
    static public implicit operator RomanNumeral(BinaryNumeral binary)
    {
        return new RomanNumeral((int)binary);
    }
    static public explicit operator int(RomanNumeral roman)
    {
         return roman.value;
    }
    static public implicit operator string(RomanNumeral roman) 
    {
        return("Conversion not yet implemented");
    }
    private int value;
}

struct BinaryNumeral
{
    public BinaryNumeral(int value) 
    {
        this.value = value;
    }
    static public implicit operator BinaryNumeral(int value)
    {
        return new BinaryNumeral(value);
    }
    static public implicit operator string(BinaryNumeral binary)
    {
        return("Conversion not yet implemented");
    }
    static public explicit operator int(BinaryNumeral binary)
    {
        return(binary.value);
    }

    private int value;
}

class Test
{
    static public void Main()
    {
        RomanNumeral roman;
        roman = 10;
        BinaryNumeral binary;
        // Perform a conversion from a RomanNumeral to a
        // BinaryNumeral:
        binary = (BinaryNumeral)(int)roman;
        // Performs a conversion from a BinaryNumeral to a RomanNumeral.
        // No cast is required:
        roman = binary;
        Console.WriteLine((int)binary);
        Console.WriteLine(binary);
    }
}

Output

10
Conversion not yet implemented

Code Discussion

  • In the preceding example, the statement:
    binary = (BinaryNumeral)(int)roman;
    

    performs a conversion from a RomanNumeral to a BinaryNumeral. Because there is no direct conversion from RomanNumeral to BinaryNumeral, a cast is used to convert from a RomanNumeral to an int, and another cast to convert from an int to a BinaryNumeral.

  • Also the statement:
    roman = binary;
    

    performs a conversion from a BinaryNumeral to a RomanNumeral. Because RomanNumeral defines an implicit conversion from BinaryNumeral, no cast is required.

See Also

C# Tutorials

Show:
© 2014 Microsoft