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

本文关键字:泛型类型 转换 | 更新日期: 2023-09-27 17:54:12

我有一个方法,看起来像这样(假设我有必要的方法getmyserializeddatarry()和我的序列化器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;
    }

然而,我想使用相同的方法来可选地,当且仅当泛型类型指定为string时,返回未序列化的数据,像这样(不编译并有语法问题):

    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"answers"are"操作符的排列,我知道在这种情况下我实际上有正确的字符串....如何保证编译器是好的?

提前感谢。

编辑:解决方案

多亏了李和洛伦兹。我将创建两个公共方法,但在一个私有方法中实现代码,并使用公认的恼人的决策树来决定是否退出序列化。我的理由是,我的真实世界的方法比我在这里向SO提出的要复杂得多,我不想复制那些业务规则。

FINAL EDIT: CHANGED SOLUTION

虽然两个答案都很有帮助,但我现在已经能够理清业务规则,因此对我来说,"正确"的答案现在是第一个——两种不同的方法。再次感谢大家。

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

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

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

这种方法的优点是

  1. 更具可读性(imo) GetSerializedMyListOfData() vs GetMyListOfData<string>(true)
  2. 你也知道调用者的意图在编译时,不必抛出一个异常当类型参数不匹配的意图留下序列化的数据

可以先转换为object:

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

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