如何将泛型类型转换为非泛型类型

时间:2014-03-26 19:05:51

标签: c# generics

我有一个看起来像这样的方法(假设我有必要的方法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;
    }

我的问题在于内联注释....基本上虽然编译器显然不喜欢泛型到非泛型的转换,但它不会让我使用“is”和“are”运算符的排列,我知道在这种情况下我实际上有正确的字符串....如何确保编译器没问题?

非常感谢提前。

编辑:解决方案

感谢Lee和Lorentz。我将创建两个公共方法,但是在私有方法中实现代码,其中包含关于是否要离开序列化的公认的决策树。我的理由是,我的真实世界方法远比我在此提出的方法复杂得多,而且我不想复制这些业务规则。

最终编辑:更改解决方案

虽然这两个答案都非常有用,但我现在能够解决业务规则,因此对我来说“正确”的答案现在是第一种 - 两种不同的方法。再次感谢所有人。

2 个答案:

答案 0 :(得分:6)

您不应该将字符串列表作为T列表返回。我建议您使用两个单独的方法并跳过参数:

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

public static List<string> GetSerializedMyListOfData()

这种方法的优点是

  1. 它更具可读性(imo)GetSerializedMyListOfData() vs GetMyListOfData<string>(true)
  2. 您还知道调用者在编译时的意图,并且当type参数与保留数据序列化的意图不匹配时不必抛出异常

答案 1 :(得分:2)

您可以先转换为object

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

然而,更清晰的解决方案可能是创建另一种处理字符串的方法,这也允许您删除leaveSerialized参数。