Wednesday, August 25, 2010

Switch Case Replacement With Resource Files

Right, one of the problems I've encountered a couple of times in regards to resx files, is that while they're awesome for providing an easily centralised way to store settings, by their very nature, they're not constant values.

So when you try to use something like:
switch ( CheckValue )
{
case ResourceItemFields.PatientResourcesPage:
case ResourceItemFields.TreatmentGuidelinesPage:
...
break;
case ResourceItemFields.ModuleData:
...
break;
}


you run into problems, because the compiler can't reference the values as a constant value, so it throws "A constant value is expected".

One solution around this is something that I've also used in Lua (as that language does not have switch/case at all), and that is to have a dictionary with the values as a function call.

private Dictionary<string, Func<ResourceItem, string>> TitleMapping = new Dictionary<string, Func<ResourceItem, string>>() 
{
{ResourceItemFields.PatientResourcesPage, rItem => rItem.Item[ ResourceItemFields.Title ]},
{ResourceItemFields.TreatmentGuidelinesPage, rItem => rItem.Item[ ResourceItemFields.Title ]},
{ResourceItemFields.ModuleData, rItem => rItem.Item[ ResourceItemFields.ModuleTitle ]},
};

public string Title
{
get
{
if ( TitleMapping.ContainsKey(Item.TemplateName) )
return TitleMapping[ Item.TemplateName ]( this );
return "";
}
}


Easily doable in Lua, as functions are first class values, and now viable in C# with the Func<T,TResult> declaration. You can also use Action<T> if you don't need to return any result. You can probably do this with delegates in 2.0, but the newer Func/Action calls are much easier to grok, imo.