Forgotten c-sharp language features: implicit operator

Note:  This post has been added to The Code Project at: http://www.codeproject.com/Tips/452213/Forgotten-Csharp-language-features-implicit-operat

Every now and again, I run into a situation when coding that makes me think: “Isn’t there a native c-sharp feature that does this?”  … and today I hit another one of those situations.

I was writing some code to isolate the conversion of one class to another.  I knew this conversion was going to be done in several locations throughout my codebase, so I wanted to write the conversion once and re-use that function.

My initial impulse was to write a static class and use a .Net 3.5 extension method similar to those we see when using LINQ.  I wrote some code that looked like:

public static class Converters {
    
    public static Receipt AsReceipt(this Order myOrder) {

        return new Receipt {
            // set properties in the Receipt from the Order object
        };

    }
}

I could then call this code as follows:

Receipt thisReceipt = myOrder.AsReceipt();

Clean… simple… easy.

But then it hit me: I can do this automatically with the implicit operator keywords.  Here is the link to the technical article on MSDN describing the feature:

http://bit.ly/implicitCsharp

To summarize that article: this feature allows us to define how to implicitly convert to and from an enclosing user-defined reference type (a class) with a static method.  Sweet!  I moved my code from the static “Converters” class back into the Receipt class and it now looks like:

public class Receipt {

    // other properties and methods...

    public static implicit operator Receipt(Order myOrder) {

        return new Receipt {
            // set properties in the Receipt from the Order object
        };
    }
}

and now my code to perform the conversion looks like this:

Receipt thisReceipt = myOrder;

That made my code so much easier to manage without having to litter static classes with conversion functions or use interfaces throughout my code.  As an additional benefit, now my Receipt object is now aware of how to convert to and from other types.  I prefer the isolation of this conversion logic, as it keeps me from searching my codebase to determine how best to convert from one custom type to another.

If you would prefer to be more declarative in the conversion statement, there is also an explicit operator keyword that you can use in the same fashion.  If you were to mark the conversion function as explicit operator, the usage statement would then look like this:

Receipt thisReceipt = (Receipt)myOrder;

We still maintain a very simple syntax that is descriptive of the code operation desired.  

Conclusion

These operator keywords are a powerful tool, one that many of us don’t know about or we forget that they are available to us.  Let’s try to make better use of these native language features, as they will help us improve our class design by keeping all of our object’s conversion concerns in one location.

I have a few more of these ‘forgotten features’ that I’ll highlight over the next few weeks.  I hope you check back to catch some of the other language features that I intend to discuss in the future.

Until next time, may all your code compile, and all of your unit test pass!