泛型可以用来折叠这些方法吗?

时间:2011-01-25 16:38:44

标签: c# generics

我有两个方法可以执行非常相似的操作,但返回类型不同(string vs int)

他们是:

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

是否可以使用泛型将这些组合成一种方法? (我尝试过但失败了。)

注意:我有两种不同的方法。我想扩展我对泛型的了解。所以我想我会问是否有可能。

2 个答案:

答案 0 :(得分:6)

尝试以下

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

以下是stringint

的一些示例用例
LoadAttribute(xmlElement, someName, x => x, defaultValue);  // string
LoadAttribute(xmlElement, someName, Int32.Parse, defaultValue);  // int

答案 1 :(得分:4)

是。使用Convert.ChangeType而不是特定的解析函数。

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

顺便说一句,抓住Exception通常是一个坏主意。你肯定想隐藏空引用错误吗?

由于我喜欢Jared的答案的一般性,我无法抗拒将我的重写改为他的过度:

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