使用泛型重构

时间:2010-02-04 02:05:46

标签: c# .net generics

我有一个简单的界面,例如

     bool TryGetValue(string key, out string value);
     bool TryGetValue(string key, out int value);
     bool TryGetValue(string key, out double value);
     bool TryGetValue(string key, out DateTime value);
     // only value types allowed 

     //with the implementation based on dictionary<string, object> 
     bool TryGetValue(string key, out string value)
     {
        object rc;
        if ( dict.TryGetValue(key, out rc) )
        {
            value = rc.ToString();
            return true;
        }

        value = null;
        return false;
     }

看起来像泛型的完美案例

     bool TryGetValue<T>(string key, out T value) where T: ValueType;

除了不能解决func实现之外,还有谁?

UPDATE - 以下不编译,我想避免创建多个TryGet ... funcs!

     bool TryGetValue<T>(string key, out T value)
     {
         return dict.TryGetValue(key, out value) ;
     }

6 个答案:

答案 0 :(得分:5)

我猜你想要的是这个:

 bool TryGetValue<TValue>(string key, out TValue value)
 {
    object rc;
    if (dict.TryGetValue(key, out rc))
    {
        value = (TValue)rc;
        return true;
    }

    value = default(TValue);
    return false;
 }

如果这些值是错误的类型,这实际上并不转换 - 它假定位于字典中的通用System.Object实例实际上属于TValue类型<{1}}方法被调用。

如果要将方法限制为仅允许泛型参数的值类型,只需将方法签名更改为:

TryGetValue

注意 - JaredPar有第一个答案,但似乎已经删除了他,所以我取消了我的,因为我认为这是OP想要的。我为任何意外的重复道歉。

答案 1 :(得分:1)

试试这个:

public bool TryGetValue<T>(string key, out T value) where T : struct
{
  object obj;
  var result = dict.TryGetValue(key, out obj);
  value = (T)obj;
  return result;
}

这不是很好,但处理out的限制...也许有人可以缩短它?如果是这样评论......总是要学习新方法。

答案 2 :(得分:0)

看看:http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx它可能对您有用。为什么不只是扩展词典?

答案 3 :(得分:0)

我相信Aaronaught已经抓住了问题的主要症结(捕获object并将其转换/取消装箱到T),但还有其他一些要点:

  • 限制为值类型(*),您使用的是where T : struct,而不是where T : ValueType ...
  • ...但请注意,string 不是值类型,因此这可能不是一个好的“适合”
  • ...和(* =)请注意where T : struct也排除了Nullable<T>

所以我认为你只需要完全删除那个约束。

答案 4 :(得分:0)

我可能会选择这样的东西,尽管Marc指出struct约束不允许使用字符串:

private static class Container<T> where T : struct
{
    public static Dictionary<string, T> Dict = new Dictionary<string, T>();
}

public bool TryGetValue<T>(string key, out T value) where T : struct
{
    return Container<T>.Dict.TryGetValue(key, out value);
}

答案 5 :(得分:0)

扩展方法。

namespace AssemblyCSharp
{
    public static class ExtentionMethod {

        public static bool TryGetValue<T, T2>(this Dictionary<T, T2> dict, string key, out T value) {
            return dict.TryGetValue(key, out value);
        }
    }
}