C# Explicit Operator – When to Implement It?

cobject-orientedtype casting

Follow-up of Is my usage of explicit casting operator reasonable or a bad hack?

One of the users commenting on that question said that it's really bad if the casting operator creates a new object under the hood, as it ceases to be an actual cast. It is of course very valid point.

When one would use the ability of defining custom type conversion? Especially: between two types that are not related by inheritance in any way.

With related objects it makes (some) sense:

class Animal {
    public string Name {get;set;}
    public int Age {get;set;}
}

class Dog : Animal {
    public void Bark(){}
    public void Fetch(){}
}

class Cat : Animal {
    public void Meow(){}
    public void Sleep(){}
}

Although normally casting Cat to Dog wouldn't be possible, it makes sense to explicitly allow it – they share all their data, just the behaviour is different.

Even when there would be some difference in fields:

class Parrot : Animal {
    public int WingSpan {get;set;}

    public void Screech(){}
}

casting still might be desired (Parrot to Cat for example, as Cat doesn't have MORE data than Parrot).

But what about two types that are not related? It is possible to do:

class Rock{
    public int Age {get;set;}
}

and

public static explicit operator Rock(Cat cat){
    return new Rock{Age = cat.Age};
}

but why? As pointed out in related question it would cause quite strange behaviour:

var cat = new Cat{Name = "Fluffy", Age = 8};
var rock = (Rock) cat;
rock.Age = 100000000;
Console.WriteLine(rock.Age); // 100000000
Console.WriteLine(cat.Age); // 8

Can anyone give a good example of when implementing explicit operator between unrelated types makes sense and how to do it?

Best Answer

Can anyone give a good example of when implementing explicit operator between unrelated types makes sense and how to do it?

I will argue that it never makes sense to overload the explicit conversion operator. That operator has a well defined behavior, and using it for a different behavior will always fall into the realm of "clever". Just use a function.

That said, I've used the implicit conversion operator a few times, and I think that it can be used in a net-positive way.

For example, I have a small programming language I'm working on. It has an object to represent an Identifier token in the syntax tree, which is just a wrapper for a string to give it a concrete type (like this recent question asked about). So instead of writing new Identifier("blah") or if(identifer == new Identifier("class")) everywhere, I have an implicit conversion from string to Identifier. It simplifies the code while keeping the behavior clear.

Yes, it does create a new object during conversion. Yes, it requires me to make sure that Identifier has value-style equality and be sure that my class design won't cause horrible problems. But it's is one of those fairly dangerous tools you can use in a few situations to make things a lot more elegant if you know what you're doing.

Explicit conversion overrides have no such upside. They add verbosity to code anyways, so you're always better off using more conventional approaches.

Related Topic