Implicit and explicit conversion operators

Implicit and explicit conversion operators allow you to ingegrate your custom types seamlessly with other types by doing implicit or explicit conversions from one type to another.

    public void SetPositionFromVector3(Vector3 vector) {
        // Do stuff.
    }

    MyType myType = new MyType(0,0,0);
    SetPositionFromVector3(myType); // Argument type 'MyType' is not assignable to parameter type 'Vector3'

If you’ve ever experienced one of those situations where you have your awesome custom type MyType which is essentially a Vector3, or what ever, with some extra spices that you really need … but now you can’t pass it to anything that really wants a Vector3. And you end up doing all kinds of weird things like exposing a special property or using inheritance and polymorphism to get it working…

Do not fret! We’ll have none of those shenanigans. implicit and explicit conversion operators to the rescue!

Let’s look at a simplification of how implicit operator is used.

class MyType {
    private Vector3 _myValue;
    public float x => _myValue.x;
    public float y => _myValue.x;
    public float z => _myValue.x;
    public static implicit operator Vector3(MyType myType) => _myvalue;
    //  ^    ^       ^        ^       ^        ^-- Input type    ^-- Return value
    //  |    |       |        |       `-- Output type
    //  `----`-------`--------`-- Magical keywords
}

That’s how you get it working. But lets examine this declaration word by word and break it apart.

All the operators have to be declared public and they also have to be static. Next we declare the implicit or explicit keyword. What implicit means is basically “Don’t ask stupid questions, just do the conversion for me - implicitly, automatically, ie. it is implied.” (The explicit keyword will be explained further down below). Next up we have to use the operator keyword which allows overloading existing C# operators. Then we have Vector3 as the type which we overload, ie. essentially our “return type” if you allow such a simplification. In the parameters we have the type we are converting from. In our function body we define how the correct value gets returned. In this example we simply return the value from the private field _myValue.

The explicit keyword works in pretty much the same way as the implicit keyword, except you have to do the casting yourself, explicitly, when you use it, eg.

    MyType myType = new MyType(0,0,0);
    SetPositionFromVector3((Vector3) myType); // explicit casting is required with explicit keyword.

Instead of implicitly as shown below.

    MyType myType = new MyType(0,0,0);
    SetPositionFromVector3(myType); // with implicit keyword casting is done automatically.

NOTE: If you decide to use the implicit keyword, you have to be careful because it will be less obvious what is going on in the code.

To do the conversion the other way around, ie. in our example from Vector3 to MyType, we can simply switch the places of the types and make sure somehow that the correct type and values are returned.

class MyType {
    private Vector3 _myValue;
    // This is what we did before.
    public static implicit operator Vector3(MyType myType) => _myvalue;
    // Here we switched things around.
    public static implicit operator MyType(Vector3 myType) => new Vector3(myType.x, myType.z, myType.z);
}