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