2014-03-26 182 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

我要在这里分化它的差异。正如洛伦兹所暗示的两种公开方法,但都是在引擎盖下使用相同的私人方法,并使用@李的方法... –