I needed some elegant method to read registry values in my Live Writer Delicious bookmarks plug-in. RegistryKey has GetValue() method but it returns values as object. I wrote generic version of GetValue() as RegistryKey extension method. It returns you specified value from key and converts it to type you ask. If conversions are not successful then default value of given type will be used.
I have two overloads for GetValue<T>(). First of them wants only value name to be specified. Second one expects also default value that is returned in the case of problems. I give some credits to Tony Wright whose blog entry How to add a ToNumber C# language extension method to the String class calling TryParse using reflection gave me some directions.
Here are my extension methods. Don’t forget to import Microsoft.Win32 namespace.
public static T GetValue<T>(this RegistryKey key, string name)
{
return key.GetValue<T>(name, default(T));
}
public static T GetValue<T>(this RegistryKey key, string name, T defaultValue)
{
var obj = key.GetValue(name, defaultValue);
if (obj == null)
return defaultValue;
try
{
return (T)obj;
}
catch(InvalidCastException)
{
}
if (typeof(T) == typeof(string))
{
obj = obj.ToString();
return (T)obj;
}
var types = new[]{typeof(string),typeof(T).MakeByRefType()};
var method = typeof (T).GetMethod("TryParse", types);
if (method == null)
return defaultValue;
var valueString = obj.ToString();
T value = defaultValue;
var parameters = new object[] {valueString, value};
method.Invoke(obj, parameters);
return (T)methodParams[1];
}
Example
And here is my little example.
var softKey = Registry.CurrentUser.OpenSubKey("Software");
var myKey = softKey.OpenSubKey("MyAppSettings");
showTitle.Checked = myKey.GetValue<bool>("ShowTitle", true);
showDescr.Checked = myKey.GetValue<bool>("ShowDescriptions");
That’s it. If you know better solution for reading registry keys or you find bugs here then please feel free to drop me a line. All your feedback is very welcome.
View Comments (3)
looks very handy :) Thx!
instead of:
try
{
return (T)obj;
}
catch(InvalidCastException)
{
}
you should use:
if(obj is T)
return (T)obj;
Always avoid an exception where is possible.
Anyway, I liked your idead, but I think things as GetInt32, GetBoolean, GetString would be more handy.
Thanks for feedback, Henrique :)
I chose generic method because I didn't want to introduce more than one method.