This is Part 3 of a series on generic parsing. Here are parts 1 and 2.
One of the more common things to do with TryParse is to assign a default value if parsing fails. Since TryParse is required to assign a value to the output parameter, it first assigns a value of its own choosing, usually default(T), which may not always be the desired default value. Testing for default(T) doesn't advise failure because it could be a legitimately parsed value. Often, we find ourselves writing the following:
int i;
if (!int.TryParse(s, out i))
i = defaultValue;
Having to repeatedly write these 3 lines can become cumbersome so sometimes we end up writing a few wrapper methods for the types we need. Of course, writing a similar wrapper around TryParse<T> is pretty easy. This is what I've done with ParseDefault<T> and ParseDefault.
Like Parse<T> and TryParse<T>, ParseDefault<T> has a non-generic counterpart that does the heavy lifting. Since ParseDefault is also public, it needs to verify that the default value is compatible with the type being parsed, so it uses the CheckDefault method to do that.
CheckDefault handles things differently depending on the type being parsed. For reference types, it makes sure that the default value is null or is type-compatible with the type being parsed. For nullable value types, it makes sure that the default is null or is of the type being parsed (nullable or not). For non-nullable value types, it makes sure that the types are the same.
Once we know the default is acceptable, we can rewrite the earlier code to use the non-generic TryParse:
public static object ParseDefault(this string s, Type type, object defaultValue)
{
if (type == null)
throw new ArgumentNullException("type");
CheckDefault(type, defaultValue);
object result = null;
if (!TryParse(s, type, out result))
return defaultValue;
return result;
}
public static T ParseDefault<T>(this string s, T defaultValue)
{
return (T)ParseDefault(s, typeof(T), defaultValue);
}
In combination with methods to get values from configuration, a query string, or whatever else, this simplifies a lot of TryParse usages scenarios.
Be sure to check out part 4.
Attachment: GenericParsing.zip
0 comments :: Generic Parsing, Part 3: ParseDefault<T>
Post a Comment