Monday, November 29, 2010

Casting Enums

I had to think hard today on how to cast back to an Enum from an int using Reflection, so seems like a good topic to recap on. If you know what you want to cast it to thats easy, just cast it, but what if you have an instance of Type and you want to cast it to that type?

I think everyone knows that enums are based on integers (32 bit or 64 bit), and sometimes it makes sense to use flag enums where each individual bit in a series of bytes represents one element of the enum. Effectively allowing an enum value to represent two or more values simultaneously.

Why do you need to cast enums to ints or strings occasionally? Sometimes this is necessary for persistence (to database or other long term storage mechanism) or communication serialisation reasons.
In these examples I'll use this enum (generally for a non-flags enum you do not set the values): 

public enum SomeFlags { Default = 4096, Email = 16384, Mobile = 32768, LandLine = 8192, Fax = 1, }

To and From Strings

SomeFlags x = SomeFlags.Email;
string str = x.ToString();
Variable str will now equal "Email".

SomeFlags x = (SomeFlags)Enum.Parse(typeof(SomeFlags), "Email");
Variable x will now be of type SomeFlags and set to value SomeFlags.Email. As you can see this method creates a rather bad dependency on those string enum names never changing.

Don't rely on Enum.GetName(Type, String) this will only work if there is an exact match.  If you are using a Flags enum and it is set to two or more values simultaneously (ie using a binary OR) this method  will not work.

To and From Integers
SomeFlags x = SomeFlags.Email; 
int value1 = (int)x;
Variable value1 is now equal to 16384.

int y = 16384;
SomeFlags x = (SomeFlags)Enum.ToObject(typeof(SomeFlags), y);
Variable x is now of type SomeFlags and is set to SomeFlags.Email.

Same comment as above applies here do not rely on Enum.GetName(Type, Int) this will not work for flag enums when they are set to two or more values simultaneously using a binary OR.

Other Casting
There is also a EnumConverter class, but you should never directly create this class. Rather call the GetConverter static method of the TypeDescriptor class. This converter is designed to handle the internals of how to convert to and from strings.

See Also
Don't forget about the other handy conversions available on the Convert static class. Especially the dynamic runtime convert Convert.ChangeType(destinationType, object).

Thursday, November 25, 2010

App.Config files vs INI files vs Registry

Here's a couple of links I have found on the topic:

Monday, November 22, 2010

New Blog Host

Looks like Google have bought blogger! I noticed there was a new app available in google/apps a few weeks ago. Thanks to Google's awesome marketing strategy, ie give stuff away for free, here's my revamped blog site! I originally only used the Google apps website because it was free and with a bit of effort I could post everything I need there. But now Blogger is available its a fully featured Blogging engine, there's no reason not to upgrade.

Thanks Google!

I will be copying all my old blog posts across here manually piece by piece as time progresses. The old site will continue to be available here:

Thursday, November 4, 2010

WCF Data Services - Reflection Provider

A colleague and I have spent some time lately exploring and finally implementing a WCF Data Service.  In a nut shell this is a service interface to expose a data model over a service boundary using Linq.  Exposing a data model over a service boundary is not that special, anyone can write a service that returns an array of objects and maybe some methods that take some criteria arguments allowing return of filtered objects.  What makes this special is the fact you access the data using Linq (with some obscure and advanced Linq features disabled). Linq allows a familar means of data access from the client's point of view, and out of the box provides a huge range of data filtering, grouping, paginating and lazy loading features.

So what is this "Reflection Provider" flavour of WCF Data Services? Other providers include "Entity Framework Provider" for exposing a EF model over the wire, and "Custom Provider"; see MSDN for more details.  The reflection provider works by pointing it at a class that defines a series of properties that return IQueryable.  This exposes all the sets your data model contains.  Each individual type can relate to other types in the model but each type must have a set property defined.  The beauty about this is most of the time you have an existing object model that can be exposed, all you need is a basic class to expose the IQueryable sets.

Obviously it would be easier to use Entity Framework, but in the problem I'm working on, there is no database, just a pre-loaded in memory object graph.  Exposing it to allow querying was pretty straight forward (with a few gotchas), and enabling editing of the object model is possible too.

Here's a sample application I wrote based on extending the example on MSDN,
Basic Example.

Here's a few gotcha's that my colleague and I found along the way:

  • Every type must have a DataServiceKeyAttribute. This must point to a unique "primary-key" property on the type.
  • References to sets, ie, the many side of a one to many relationship should be of type IList<T>.
  • Enums do not get shipped across the wire for some reason. There are plenty of requests on the forums to cater for this, hopefully will appear in a future release. This can be worked around by ignoring this property and having an equivelent int property. Use the IgnorePropertyAttribute to exclude a property. On the client side the enum can be partialled back in.
  • Don't forget to use the Linq Expand method to instruct WCF to return related sets of data, by default these get excluded.

Next I had a look at performance.  I compared it to a standard WCF service where you would have to write your own methods to provide ways of returning a sensible amount of data.  Seems like a crazy comparison to do I know, but it was necessary to prove a point.  Its pretty obvious that if you choose not to use WCF Data Services you will end up writing your own query language in the form of many OperationContracts. Using Linq is far less work and a huge amount of flexibility out of the box.

The long and short of it is Linq is actually faster due to a standard service is always going to return populated (eager) related sets. This means potentially huge graphs of data being served back when the client only will use one object.  You would be able to code a way to return only the object requested but its extra work and very proprietry and extra code to debug.

Thanks Marjorie for your input, great work!