C#: Access a Resource .resx File and a Corresponding Enum To Create a Dictionary
(Update 5/16/2011: Fixed mispelling)
I ran across a situation where the code I was working on had an enum with values and I needed to display a user friendly text which was related to the enum but not the enum’s actual text value.
The standard way of mapping values across cultures is to create a localized resource file(s) (.resx) and to put in string key and a string value, where the value will be shown. The code can then do an if check to map between the two; but that gets laborious real quick. It would be better to have a dictionary where the enum is the key and the value is the value of the resources file.
The following snippet of code takes in an enum and its corresponding resource resx data and creates that dictionary. See the section Steps to Test for an example of its usage.
/// <summary> /// Take an enum and a created corresponding resx resource file and join the two together /// into a dictionary. The dictionaries key is the actual enum and the value is the user readable text /// found in the value of the resource file. /// </summary> /// <typeparam name="T">The Enum type which contains the target enums</typeparam> /// <param name="rm">The .resx resource's manager which contains the mapped text</param> /// <returns>A dictionary whose key is the enum and the result is the mapped text in the resource file.</returns> public static Dictionary<T, string> LoadResourceEnumMappings<T>( ResourceManager rm ) { T[] eValues = (T[])System.Enum.GetValues( typeof( T ) ); // Gets the actual values of the enum (T) type // Puts those into a local dictionary/hash for use in later. var dictEnum = eValues.ToDictionary( it => it.ToString(), it => it ); // Work through the key value pairs (KVP) of the resource set and marry them // to a new dictionary where the key is the enum and the value output is the user string // as found in the resource's value of its kvp. return rm.GetResourceSet( Thread.CurrentThread.CurrentCulture, true, false ) .OfType<DictionaryEntry>() .ToDictionary( kvp => dictEnum[kvp.Key.ToString()], kvp => kvp.Value.ToString() ); }
NOTES
- One can have more resource keys than enums and the above will work. But if there are more enums than resource keys, the above code will throw a KeyNotFound exception.
Enumerate the Embedded Resource
The above code uses the ability to enumerate or iterate the resource file by calling GetResourceSet. That calls returns a Dictionary entry which has the key value pair of the resource file and could be used with a foreach.
Steps To Test
- Create console application
- Create enum named MappedValues with these enums : Alpha, Beta, Gamma.
public enum MappedValues { Alpha, Beta, Gamma }
- Create Resource File named UserText.Resx with these values:
Test as such with this code by calling EnumMapper.Usage():
public static class EnumMapper { /// <summary> /// This is just for show and not meant for production. /// </summary> public static void Usage() { try { Console.WriteLine( "Load resource and show: " + UserText.Alpha ); Dictionary<MappedValues, string> mapped = LoadResourceEnumMappings<MappedValues>( UserText.ResourceManager ); Console.WriteLine( mapped[MappedValues.Alpha] ); Console.WriteLine( mapped[MappedValues.Beta] ); Console.WriteLine( mapped[MappedValues.Gamma] ); } catch ( KeyNotFoundException ) { Console.WriteLine("The Resource File has a key which is not found in the enum."); } /* outputs (Note "first value" was shown to initialize the ResourceManager otherwise it would be null from GetResourceSet) Load resource and show: First Value First Value Second Item Third Wave */ } /// <summary> /// Take an enum and a created corresponding resx resource file and join the two together /// into a dictionary. The dictionaries key is the actual enum and the value is the user readable text /// found in the value of the resource file. /// </summary> /// <typeparam name="T">The Enum type which contains the target enums</typeparam> /// <param name="rm">The .resx resource's manager which contains the mapped text</param> /// <returns>A dictionary whose key is the enum and the result is the mapped text in the resource file.</returns> public static Dictionary<T, string> LoadResourceEnumMappings<T>( ResourceManager rm ) { T[] eValues = (T[])System.Enum.GetValues( typeof( T ) ); // Gets the actual values of the enum (T) type // Puts those into a local dictionary/hash for use in later. var dictEnum = eValues.ToDictionary( it => it.ToString(), it => it ); // Work through the key value pairs (KVP) of the resource set and marry them // to a new dictionary where the key is the enum and the value output is the user string // as found in the resource's value of its kvp. return rm.GetResourceSet( Thread.CurrentThread.CurrentCulture, true, false ) .OfType<DictionaryEntry>() .ToDictionary( kvp => dictEnum[kvp.Key.ToString()], kvp => kvp.Value.ToString() ); } }