2014-03-26 181 views
1

我有一個看起來像這樣的方法(假設我有必要的方法GetMySerializedDataArry()和我的串行JsonSerializer):如何泛型類型強制轉換成非泛型類型

public static List<T> GetMyListOfData<T>() 
    { 
     var msgList = new List<T>(); 

     foreach (string s in GetMySerializedDataArray()) 
     { 
      msgList.Add(JsonSerializer.Deserialize<T>(s)); 
     } 

     return msgList; 
    } 

這工作正常和預期的一樣。

不過,我想用同樣的方法可選,當且僅當泛型類型指定爲字符串,返回去系列化這樣的數據(不編譯和有語法問題):

public static List<T> GetMyListOfData<T>(bool leaveSerialized) 
    { 
     if (typeof (T) != typeof(string) && leaveSerialized) 
     { 
      throw new ArgumentException("Parameter must be false when generic type is not List<string>", "leaveSerialized"); 
     } 

     var msgList = new List<T>(); 

     foreach (string s in GetMySerializedDataArray()) 
     { 
      if (leaveSerialized) 
      { 
       // Casting does not work: "Cannot cast expression of type 'System.Collections.Generic.List<T>' to type 'List<string>'" 
       // I've tried various permutations of "is" and "as"... but they don't work with generic types 
       // But I know in this case that I DO have a list of strings..... just the compiler doesn't. 
       // How do I assure the compiler? 

       ((List<string>)msgList).Add(s); 
      } 
      else 
      { 
       msgList.Add(JsonSerializer.Deserialize<T>(s)); 
      } 
     } 

     return msgList; 
    } 

我的問題在inline comment ....基本上雖然編譯器顯然不喜歡泛型到非泛型的轉換,但它不會讓我使用「is」和「are」運算符的排列組合,我知道我在這種情況下實際上有正確的字符串....如何確保編譯器是可以的?

非常感謝提前。

編輯:解

感謝李和洛倫茲,兩者。我將創建兩個公共方法,但用一個私有方法來實現代碼,並且使用公認的icky決策樹來決定是否要離開序列化。我的理由是,我的現實世界的方法比我在這裏提出的要複雜得多,我不想複製這些業務規則。

最後編輯:改解決方案

雖然這兩個答案是非常有益的,我現在已經能夠梳通的業務規則,並且其結果是「正確」的答案對我來說現在是第 - 兩個不同的方法。再次感謝所有人。

+2

爲什麼不簡單兩種方法?一個泛型和一個非泛型? – sloth

+0

雖然我同意@Lorentz,但另一種選擇是將'msgList'強制轉換爲'IList'而不是'IList ',並簡單地調用Add(對象項),這相當於@Lee –

+0

提出的解決方案。謝謝all - 當然,我提供了一個更簡單的我的方法版本,在我們使用msg add之前,它有很多業務邏輯。我也認爲我一般同意洛倫茲....但特別是業務邏輯的代碼重複將是一個問題。我想我會實施兩種不同方法的公共包裝,然後這兩種方法都會調用相同的私有方法,這將使用Lee提出的解決方案。我感謝所有人。 –

回答

6

你不應該返回一個字符串列表作爲T的名單,我建議你使用兩種不同的方法,並跳過參數:

public static List<T> GetMyListOfData<T>() 

public static List<string> GetSerializedMyListOfData() 

這種方法的優點是

  1. 它更具可讀性(imo)GetSerializedMyListOfData() vs GetMyListOfData<string>(true)
  2. 您也可以在編譯時知道調用方的意圖,並且在類型參數不符合意圖時不必拋出異常t o留下數據序列化
+1

我認爲洛倫茲是正確的,你應該使用兩種方法來做到這一點。使用通用方法來做到這一點似乎沒有意義。我唯一想到的其他事情就是使用一個ArrayList(可以接受任何對象),但是我認爲這可能會更復雜,除非你只是試圖轉儲到feed或者某些模糊的東西。 – jamesbar2

+0

我一直在得出這個結論。唯一的問題是我的實際方法在業務規則上要複雜得多,所以我很想要複製那些代碼。雖然可能是兩個邪惡中較小的一個。 –

+0

我打算在這裏分開差異。 @Lorentz提出了兩種公共方法,但都是在引擎蓋下調用相同的私有方法,並使用Lee的方法... –

2

可以轉換爲object第一:

((List<string>)(object)msgList).Add(s); 

然而一個清潔的解決方案可能是創建處理字符串的另一種方法,這也將讓您免去leaveSerialized參數。

+0

我要在這裏分化它的差異。正如洛倫茲所暗示的兩種公開方法,但都是在引擎蓋下使用相同的私人方法,並使用@李的方法... –