Type conversion operators in C#

Onion Blog

Syndication

I've been working on a project that uses web services on the back end, and one language feature I've found quite useful is the ability to define explicit type conversion operators in C#. In my case, there are often several classes defined in the web service layer for the same conceptual type - one for retrieving, one for updating, one for authorizing, etc. Each class has a subset of the overall fields in the underlying data store. For convenience in my UI code, I created a single class that contains all of the fields, and then implemented explicit type conversion operators for each of the types defined by the web service interface so when I invoke the back-end methods I simply cast my unified class into the needed back-end class, and the code is quite clean. Here's a simplified example of what I mean:
 
Classes defined by Web service layer (generated by WSDL import):
 
public class Item
{
  public int ID;
  public string Title;
  public DateTime Date;
  public string Status;
}
 
public class UpdateItem
{
  public int ID;
  public string Title;
  public string Status;
}
 
My unified class, used by UI elements, with explicit type conversion operators for Web service layer types:
 
public class UIItem
{
  public int ID;
  public string Title;
  public DateTime Date;
  public bool Active;
 
  public static explicit operator Item(UIItem uiitem)
  {
    Item i = new Item();
    i.ID = uiitem.ID;
    i.Title = uiitem.Title;
    i.Date = uiitem.Date;
    i.Status = uiitem.Active ? "Active" : "Inactive";
    return i;
  }
 
  public static explicit operator UpdateItem(UIItem uiitem)
  {
    UpdateItem i = new UpdateItem();
    i.ID = uiitem.ID;
    i.Title = uiitem.Title;
    i.Status = uiitem.Active ? "Active" : "Inactive";
    return i;
  }
}
 
A sample method that casts the unified class into the necessary type for invoking the Web service:
 
ws.UpdateItem((UpdateItem)uiitem);
 
Note that I used all explicit type conversion operators in this case since the operations were not lossless (well, in my simple example one of them was lossless, but in my real-world example they weren't). You can also create implicit type conversion operators if it makes sense (the conversion is lossless).
 
The flip-side of this is to also write constructors in the UIItem class that take both Item and UpdateItem as a single parameter, which you typically also want to do for convenience of initialization going the other way. Something like:
 
public UIItem(UpdateItem i)
{
  this.ID = i.ID;
  this.Title = i.Title;
  this.Active = i.Status == "Active";
}
 
I used to use type conversion operators in C++ quite a bit, but I rarely see any reference to them in C#, so I thought I'd blog about them to help raise awareness. I think they can help clarify and clearly define the transition from one type to another, and when used properly can make code much more readable. This is not a new 2.0 feature, by the way - it's been around since the beginning :)
 
 

Posted Dec 09 2005, 09:01 AM by fritz-onion
Filed under:

Comments

CraigBlog wrote C# Type Conversion Operators Considered Harmful
on 12-09-2005 10:24 AM
Christopher Steen wrote Link Listing - December 9, 2005
on 12-09-2005 6:20 PM
Another Son of SmartPart QuickStart [Via: Jan
Tielens ]
C# Type Conversion Operators Considered ...
Sean Chase wrote re: Type conversion operators in C#
on 12-10-2005 11:08 AM
Great post Fritz!!! I actually have to do this quite a bit and I've been using constructor logic instead. This is SO much nicer.
David Taylor wrote re: Type conversion operators in C#
on 12-12-2005 2:49 AM
Great post....I have been aware of this since the beginning back in July 2000, but other than paying in the early days, have never actually used this technique in my projects.

It definately is a technique/feature worth considering in certain cases.
David Taylor wrote re: Type conversion operators in C#
on 12-12-2005 2:53 AM
BTW Fritz, I should add that one of the issues I am currently grappling with is the best way to augment the classes auto-generated from WSDL in V2.0.

It is a little frustrating that you have this great partial class feature, but by default ASP.NET compiles the web references into a separate assembly, so you cannot use partial classes unless you drag the WSDL into the App_Code directory....which is a little ugly and the generated proxy loses the namespace (auto-generated from the directory name when using web references).

Of course, the new stuff the ASP.NET team has been announcing with more compilation options (a single assembly, etc) would fix this....but I would not want to "force" a compilation and project model decision just for a simple issue like this....and would prefer to stick to the out of the box compilation model.

Anyway...I am just playing, looking at the different ways to intercept the code generated by WSDL, and other such options....looking to see what is the most elegant.


Bertrand Le Roy wrote re: Type conversion operators in C#
on 12-12-2005 2:04 PM
IMHO it all boils down to (someObject == (SomeType)someObject) being false with your code, which looks very wrong.
Fritz Onion wrote re: Type conversion operators in C#
on 12-12-2005 3:21 PM
Craig posted a similar sentiment to yours, Bertrand:
http://pluralsight.com/blogs/craig/archive/2005/12/09/17351.aspx

and we had some interesting discussion in his comment section. I now agree that this messes with the concept of identity in such a way as to make it potentially dangerous, and am now inclined to use explicit methods for all such conversions. I'll post a followup entry with this conclusion in case others didn't see Craig's post.

Onion Blog wrote Type conversion operators in C# revisited
on 12-12-2005 3:46 PM
Pedro Felix wrote Blog interaction: a "C# conversion operators" tale
on 12-13-2005 5:07 PM
A first post on the benefits of the usage of C#'s "conversion operator": http://pluralsight.com/blogs/fritz/archive/2005/12/09/17343.aspx...
Dinis Cruz @ Owasp .Net Project wrote FireFox Tab Dump – 14 Dec 2005
on 12-13-2005 6:50 PM

Since FireFox just
stopped responding (i.e. opening up new pages, but at least didn't
die (like it...
james peckham wrote re: Type conversion operators in C#
on 05-15-2007 9:35 AM
my problem with type conversion operators is it forms a dependency between the types. Most of the time i want to convert between types is to help decouple components. For example in a service oriented model my service implementation knows about my contracts and business entities assemblies, but i don't want my contracts and entities assemblies to know about eachother. So it's best for me to have a type within my service implementation that knows how to convert between each of them. This way changes to my Entities never break my contract definitions (only my service implementation converters, which can be changed without affecting the client application)
Anonymous Programmer wrote re: Type conversion operators in C#
on 09-03-2008 12:49 PM

High Integrity CPP Rule 3.1.11

-----------------------------------------------

Do not provide conversion operators for class types. (QACPP 2181) Justification Conversion operators should not be used because implicit conversions using conversion operators can take place without the programmers knowledge. Conversion operators can lead to ambiguity if both a conversion operator and a constructor exist for that class. In most cases it is better to rely on class constructors.

class C;

class D {

 public: D( C ); // 1

};

class C {

 public: operator D(); // 2

};

void foo( D );

void bar() {

 C c;

 foo( c ); // ambiguous (convert to D by 1 or 2?)

}

See also Rule 3.1.10

Add a Comment

(required)  
(optional)
(required)  
Remember Me?