2010-02-04 95 views
2

我有一个方法,如重构使用泛型

 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实施,任何一个简单的界面?

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

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

回答

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限制......也许有人可以缩短甚至更多?如果是的话评论...总是要学习新的方式。

+0

看到更新以上 – Kumar 2010-02-04 02:20:00

+0

@Kumar - 更新了答案...希望这就是你以后,如果不是请让我知道你错过了什么。 – 2010-02-04 02:38:53

0

看看:http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx它可能证明对你有用。另外为什么不只是扩展字典?

+0

商业规则 - 必须是基本价值类型 – Kumar 2010-02-04 02:16:33

+0

嗯,你必须原谅我这一个,但基本的价值类型会是什么? http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx这就是msdn所说的关于值类型(结构/枚举)与用户定义是其中之一。 – Woot4Moo 2010-02-04 06:28:12

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实例在调用TryGetValue方法时实际上是TValue类型。

如果你想限制方法只允许值类型为通用参数,只是改变了方法签名本:

bool TryGetValue<TValue>(string key, out TValue value) where TValue : struct 

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

+0

当存在一个与键关联的对象时,返回'false'而不是抛出一个InvalidCastException可能会更好,但它是错误的类型。 – 2010-02-04 02:38:48

+0

@Anon:我可以看到它。如果你返回'false',那么这本字典对你说谎;它说它没有钥匙,但确实如此。如果你有一个典型的'if(!lookup.TryGetValue(key,out value)){lookup.Add(key,newValue)}',那么它会意外失败。这取决于如何使用这个类,但是,我可以看到一些情况,其中简单地返回'false'将是期望的结果。 – Aaronaught 2010-02-04 02:43:57

+0

这将工作,以避免您在评论中描述的情况,任何方式来声明字典其中T:ValueType没有子类? – Kumar 2010-02-04 03:03:50

0

我相信Aaronaught已经抓住了问题(捕获object和铸造/拆箱到T)的主要症结,但一些附加分:

  • ,以限制值类型(*),你使用where T : struct,不where T : ValueType ...
  • ...但要注意,string值类型,所以这可能不是一个很好的“适合”
  • ...和(* =)注那where T : struct也排除Nullable<T>

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

0

我可能会去这样的事情,虽然正如马克指出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); 
} 
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); 
     } 
    } 
}