Implicit and Explicit Conversion Operators in C#
Recently I stumbled upon a pretty interesting feature of C# that I either neglected to really pay attention to before or just had entirely missed.
It is definitely debatable whether or not one should even use this feature, because it is likely to result in some confusing situations by someone reading your code even if they are aware of the feature’s existence.
Take a look at this code
Let’s look at an example that might look a bit strange.
What would you think if you stumbled upon this code?
What if I told you that Book does not inherit from XDocument?
In this case a custom implicit casting is happening because of an implicit conversion operator I created on Book.
Here is how it is defined:
What is happening in this case is that the compiler is noticing that I am trying to assign a Book object to a variable of type XDocument and that I have defined an implicit operator to allow that conversion.
By defining this implicit conversion operator I can assign any Book to an XDocument and it will execute the code defined in my implicit operator method to return an XDocument.
Backwards as well
I can also make the conversion the other way.
You can see here that I am doing something a bit different though. In this case I am explicitly casting the XDocument into a Book.
I could have used implicit conversion, like the previous example, but not all XDocuments can automatically be converted to Books, so I wanted to make it allowed only if someone explicitly used the casting operator to perform the cast.
Here is what that code looks like:
You can only use the implicit and explicit operators on classes that you have defined. You can’t use them to extend existing classes to add automatic conversions.
Also the conversions can’t chain automatically. If you have a conversion to type a Dog to a Cat and a Cat to a Mouse, you can’t assign a Dog directly to a Mouse.
Should I use it?
Now that is a tough question. I have some mixed thoughts on actually using this feature.
My biggest problem with it is the discoverability. When I look at code that is assigning a Book to an XDocument, I don’t immediately know where to look for the code that is allowing that assignment. The code could actually exist in either the Book class or the XDocument class. (We happen to know in this case that XDocument is a .NET class, so it’s not going to be there, but where you have to user defined classes, you can’t be sure.)
If I didn’t know about implicit and explicit operator overloads, I would be even more puzzled.
My other reservation is that in most cases it is not immediately obvious what exactly is happening.
- Are we getting a copy of Book that is representing an XML structure?
- Are we getting a raw XML document that could be populated with Book data?
- Are we losing data here?
I can look at the method to figure out what is going on, but that makes the code that is using the implicit or explicit conversion less readable by itself.
It seems to me in that case having a method off of Book called ToXDocument() would make things at least a bit more clear.
On the other hand, I can definitely see some benefits to using these operators to make code more succinct and to make types that have obvious conversion easier to work with.
Consider having classes that represent temperatures in Celsius and Fahrenheit. In those cases implicit conversion operators between the two formats makes intuitive sense. We can also be pretty confident that the conversion would not result in a data loss.
In general, my recommendation would be to avoid defining implicit and explicit operators because it is likely that most developers reading your code will be confused by them and in most cases you are not adding much value.
I would say that you should only use implicit and explicit operators when the conversion between two types is very clear because they are just different ways of representing the same value.
Although I can see the cases for other uses of the operators, it seems like there the usage is more likely to cause confusion than bring clarity.
To me an equal sign means assignment, I do not often think of it to mean conversion.
I could of course be wrong about my thoughts on implicit and explicit operators, but as of yet I haven’t seen it in the wild, so if you have some good examples of where it makes sense to use this feature, please let me now.
If you're great at what you do, but aren't getting the compensation you deserve, you might want to check out our Simple Programmer course: How to Market Yourself as a Software Developer.