2010-02-04 37 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); 
     } 
    } 
}