I came across an interesting article the other day. It was about a “forgotten” C# feature, the implicit and explicit operators. You can see the original article here. I do remember reading something about these operators years ago, but I don’t think that I’ve seen these operators at use in the wild, though I can definitely think of a ton of times that we needed it.
If you don’t know yet, the explicit and implicit operators help with converting one object of one type into another object of another type. The best use case for this isn’t for converting simple types like ints into doubles, but for converting more complex objects. One common example would be if you are using something like nHibernate or Entity Framework that generates classes for all of your database tables. However, if you are using WCF/Web Services/Remoting/Whatever, you might have different classes that need to exist before transmission.
Let’s pretend that we have the following classes:
namespace DataClasses { public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int PersonId { get; set; } } } namespace ContractClasses { public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int PersonId { get; set; } } }
Now, we can see that the classes have the same names and identical declarations. Again, this is very simplified, but it is a real problem. This is one of the types of things that the excellent tool AutoMapper is used for. AutoMapper does this for you automatically, of course, but if you only need this for a few instances, you may not want to take a dependency. If you just try this code, you will get the error “Cannot implicitly convert type ‘DataClasses.Person’ to ‘ContractClasses.Person'”.
DataClasses.Person dcPerson = new DataClasses.Person() {FirstName = "Pete", LastName = "OnSoftware", PersonId = 7}; ContractClasses.Person ccPerson = dcPerson;
However, if you add this code into the DataClasses.Person class (either directly or with a partial), the above code now compiles.
public static implicit operator ContractClasses.Person (DataClasses.Person p) { return new ContractClasses.Person() { FirstName = p.FirstName, LastName = p.LastName, PersonId = p.PersonId }; }
That does make the code compile, but we are losing some of what is happening there. That is why the explicit operator exists. It allows you to not do a “hidden” convert, but instead make an explicit cast. If we change the code to look like this our code breaks again:
public static explicit operator ContractClasses.Person (DataClasses.Person p) { return new ContractClasses.Person() { FirstName = p.FirstName, LastName = p.LastName, PersonId = p.PersonId }; }
However, if we change our original code to this, we are back in business and much more readable.
DataClasses.Person dcPerson = new DataClasses.Person() {FirstName = "Pete", LastName = "OnSoftware", PersonId = 7}; ContractClasses.Person ccPerson = (ContractClasses.Person)dcPerson;
This isn’t limited to converting “identical” classes. Jeffrey T. Fritz, the author of the article above that inspired this post converted from an order class to a receipt class, for instance. I definitely believe that using explicit and implicit can make your code much more readable than using utility/conversion classes or extension methods to accomplish the same thing.
I saw this same article and I thought it was pretty cool, but you do lose the ability to use “var”. Which isn’t a huge deal.
Matt,
Yeah, you can’t use var with the implicit operator, but you can do
var ccPerson = (ContractClasses.Person)dcPerson;
and still keep using var with the explicit declaration.
I came across this article whilst searching the web along the lines of “What’s the point of automapper” when you can maintain complete control over casting one class to another (and any dependencies) without the overhead. Am I such a bad person?