I have two methods that do very similar things but with a different return type (string vs int)
Here they are:
private static string LoadAttributeString(this开发者_运维知识库 XElement xmlElement,
string attributeName, string defaultValue)
{
try
{return xmlElement.Attribute(attributeName).Value;}
catch (Exception)
{return defaultValue;}
}
private static int LoadAttributeInt(this XElement xmlElement,
string attributeName, int defaultValue)
{
try
{return int.Parse(xmlElement.Attribute(attributeName).Value);}
catch (Exception)
{return defaultValue;}
}
Is it possible to use generics to combine these into one method? (I tried and failed.)
NOTE: I am fine having two different methods. I would just like to expand my knowledge of generics. So I thought I would ask if it is possible.
Try the following
private static T LoadAttribute<T>(
this XElement xmlElement,
string attributeName,
Func<string, T> convertFunc,
T defaultValue) {
try {
return convertFunc(xmlElement.Attribute(attributeName).Value);
} catch (Exception) {
return defaultValue;
}
}
Here are some example use cases for string
and int
LoadAttribute(xmlElement, someName, x => x, defaultValue); // string
LoadAttribute(xmlElement, someName, Int32.Parse, defaultValue); // int
Yes. Use Convert.ChangeType instead of a specific parsing function.
private static T LoadAttribute<T>(this XElement xmlElement,
string attributeName,
T defaultValue)
where T : IConvertible
{
try
{
return (T)Convert.ChangeType(
xmlElement.Attribute(attributeName).Value,
typeof(T));
}
catch (Exception)
{
return defaultValue;
}
}
By the way, catching Exception
is generally a bad idea. Do you definitely want to hide null reference bugs?
As I like the generality of Jared's answer, I can't resist rewriting mine as a mere overload to his:
private static T LoadAttribute<T>(this XElement xmlElement,
string attributeName,
T defaultValue)
where T : IConvertible
{
return LoadAttribute(
xmlElement,
attributeName,
x => (T)Convert.ChangeType(x, typeof(T)),
defaultValue);
}
精彩评论