Writing Implicit and Explicit C# Conversion Operators

When writing custom classes we can provide behaviour to allow for both explicit and implicit conversions to other types.

Implicit conversion operators are those that don’t require an explicit cast.

Explicit conversion operators are those that do require an explicit cast.

As an example, the following code shows a simple console application to covert a weight in Pounds to Kilograms.

internal class Program
{
    private static void Main(string[] args)
    {
        WriteLine("Please enter a value in lbs");
        var lbsText = ReadLine();

        var lbs = new PoundsExplicit(float.Parse(lbsText));
        WriteLine($"\nYou entered {lbs}");

        Kilogram kg = (Kilogram) lbs;
        WriteLine($"\n{lbs} is {kg}");

        WriteLine("\nPress enter to exit");
        ReadLine();
    }
}

Notice in the preceding code the line Kilogram kg = (Kilogram) lbs; is explicitly casting from a type of PoundsExplicit to Kilograms.

The Kilogram class is defined as follows:

internal class Kilogram
{
    public float Weight { get; set; }

    public Kilogram(float weight)
    {
        Weight = weight;
    }

    public override string ToString()
    {
        return $"{Weight} kg";
    }
}

To allow the (explicit) cast from PoundsExplicit to Kilogram, the PoundsExplicit class defines an explicit conversion operator as shown in the following code:

internal class PoundsExplicit
{
    public float Weight { get; set; }

    public PoundsExplicit(float weight)
    {
        Weight = weight;
    }
    public override string ToString()
    {
        return $"{Weight} lbs";
    }

    public static explicit operator Kilogram(PoundsExplicit lbs)
    {
        const float conversionRate = 0.45359237f;

        float equivalentKgs = lbs.Weight * conversionRate;

        return new Kilogram(equivalentKgs);
    }
}

To allow the conversion to Kilogram to be implicit, with no cast required (e.g. Kilogram kg = lbs;) the operator can be changed to implicit as shown in the following class:

internal class PoundsImplicit
{
    public float Weight { get; set; }

    public PoundsImplicit(float weight)
    {
        Weight = weight;
    }       

    public override string ToString()
    {
        return $"{Weight} lbs";
    }

    public static implicit operator Kilogram(PoundsImplicit lbs)
    {
        const float conversionRate = 0.45359237f;

        float equivalentKgs = lbs.Weight * conversionRate;

        return new Kilogram(equivalentKgs);
    }
}

The main method can now be modified as follows:

private static void Main(string[] args)
{
    WriteLine("Please enter a value in lbs");
    var lbsText = ReadLine();

    var lbs = new PoundsImplicit(float.Parse(lbsText));
    WriteLine($"\nYou entered {lbs}");

    Kilogram kg = lbs;
    WriteLine($"\n{lbs} is {kg}");

    WriteLine("\nPress enter to exit");
    ReadLine();
}

Notice in the preceding code the conversion from PoundsImplicit to Kilogram now is implicit, it does not require an explicit cast.

When deciding between implicit or explicit conversion operators you should consider the resulting readability of code that uses the types. An implicit cast is more convenient whereas an explicit cast may add extra clarity/readability to the code that uses the types.

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

Comments (8) -

  • grthr

    6/5/2016 4:45:39 PM | Reply

    Nice roundup. One could mention, that implicit and explicit operators are not allowed for interfaces.

  • Jamie Bowman

    5/3/2019 7:38:37 PM | Reply

    This perfectly explains it! Thank you!

    • Jason Roberts

      5/7/2019 5:17:07 AM | Reply

      Thanks Jamie - glad it was helpful Smile

  • Christopher Townsend

    9/23/2019 8:04:50 PM | Reply

    Thanks for this. Was struggling with the difference between explicit and implicit and this explains it perfectly. Good job!

    • Jason Roberts

      10/30/2019 2:17:33 AM | Reply

      Thanks Christopher - glad to be of help Smile

  • Vasil Kosturski

    2/16/2020 8:19:15 PM | Reply

    Thanks for the great article. Explains pretty well the behavior of conversion operators. However, just decided to mention that in my opinion in most of the cases we should avoid them. They enable some magical types substitutability, which from my perspective can be a little hard to grasp at times. Plus, there is a specific use case that can cause problems that are not so easy to troubleshoot. Most often this happens in case of a function which changes its input param state, but the input param is passed through a conversion operator. In this case the passes object would be a temporary object produced by the conversion operator which becomes garbage right after the function returns. So, the object that is owned by the caller would not get modified. I’ve dealt with such a production issue recently so decided to share my experience on a blog post on avoiding conversion operators where I’ve given a quite detailed example: https://vkontech.com/avoid-conversion-operators/ I’d love to hear your opinion.

    • Jason Roberts

      2/18/2020 7:14:02 AM | Reply

      Thank Vasil Smile

  • Mohamad

    2/27/2020 4:54:52 AM | Reply

    I think that your code would be much more meaningful  by using Explicit type!

Pingbacks and trackbacks (5)+

Add comment

Loading