开发者

Can generics be used to collapse these methods?

开发者 https://www.devze.com 2023-02-06 11:54 出处:网络
I have two methods that do very similar things but with a different return type (string vs int) Here they are:

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);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消