C# Operators: Conversion Operators (implicit / explicit)

December 13, 2010 by C#  

Within C# (among other languages) we've got the ability to overload implicit / explicit conversion operators.

Just to get everyone up to speed, an implicit conversion refers to an action that happens automatically (the compiler infers - decides what the appropriate type is to use) e.g.

Decimal d = 10.9M;

While an explicit conversion refers to the opposite - a developer needs to manually specify to which type they wish to cast an object e.g.
int i = (int)d; // d being the decimal value from the preceding snippet

In the following snippet we've got two structs, one represents kilograms (you know metric?) and the other one pounds.
struct Pound
{
    public Pound(float value)
    {
        this._Value = value;
    }

    private float _Value;
    public float Value
    {
        get { return _Value; }
    }

    public static implicit operator Pound(float value)
    {
        return new Pound(value);
    }

    public static explicit operator Pound(Kilogram value)
    {
        return new Pound(value.Value * 2.20462262f);
    }
}

struct Kilogram
{
    public Kilogram(float value)
    {
        this._Value = value;
    }

    private float _Value;
    public float Value
    {
        get { return _Value; }
    }

    public static implicit operator Kilogram(float value)
    {
        return new Kilogram(value);
    }

    public static explicit operator Kilogram(Pound value)
    {
        return new Kilogram(value.Value * 0.45359237f);
    }
}

In the snippet above, our "base" value is a float, from which an implicit conversion happens e.g.
Pound p = 100; // public static implicit operator Pound(float value)

And we require the developer to do an explicit cast if they wish to convert pounds to kilogram e.g.
Kilogram kg = (Kilogram)p; // public static explicit operator Kilogram(Pound value)

But how does one decide whether an operator conversion should be implicit or explicit? As a rule of thumb we can use implicit casting when there is no risk of information loss and not throw any exceptions from our overload. (basically we want our implicit conversion to have expected results)

Loss of information? If you look at the explicit conversion in the second snippet in this post (decimal to int) - you will notice that the integer conversion's actually flooring the decimal - which means we're losing our decimals. (loss of information)


Leave a Comment