简体   繁体   English

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

[英]How to cast a generic type to a non-generic type

I have a method that looks like this (assume that I have the necessary method GetMySerializedDataArry() and my serializer JsonSerializer): 我有一个看起来像这样的方法(假设我有必要的方法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;
    }

This works fine and as expected. 这工作正常,并且符合预期。

However, I want to use the same method to optionally, if and only if the generic type is specified as string, return the data unserialized like this (which does not compile and has syntax problems): 但是,我希望使用相同的方法来选择,当且仅当将泛型类型指定为字符串时,才返回未序列化的数据,如下所示(它不会编译并且存在语法问题):

    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;
    }

My questions are in the inline comment.... basically though the compiler clearly doesn't like the cast of generic to non-generic, it won't let me use permutations of "is" and "are" operators either, I know I actually have the correct string in this case.... how to assure the compiler it is OK? 我的问题在内联注释中。...尽管编译器显然不喜欢将泛型转换为非泛型,但我也不会使用“ is”和“ are”运算符的组合在这种情况下,我实际上具有正确的字符串。...如何确保编译器正常?

Many thanks in advance. 提前谢谢了。

EDIT: SOLUTION 编辑:解决方案

Thanks to Lee and Lorentz, both. 感谢Lee和Lorentz,两者。 I will be creating two public methods, but implementing the code in a private method with the admittedly icky decision tree about whether to leave serialization. 我将创建两个公共方法,但是将使用公认的棘手的决策树(关于是否要离开序列化)在私有方法中实现代码。 My reason is that my real-world method is far more complex than what I posed here to SO, and I don't want to duplicate those business rules. 我的理由是,我的实际方法要比这里给SO提出的方法复杂得多,并且我不想重复这些业务规则。

FINAL EDIT: CHANGED SOLUTION 最终编辑:更改的解决方案

Although both answers were very helpful, I have now been able to detangle business rules, and as a result the "correct" answer for me is now the first -- two different methods. 尽管这两个答案都非常有帮助,但是我现在能够理清业务规则,因此对我来说,“正确”答案现在是第一个-两种不同的方法。 Thanks again to all. 再次感谢大家。

You should not return a list of strings as a list of T. I would suggest that you use two separate methods and skip the parameter: 您不应该将字符串列表作为T的列表返回。我建议您使用两种单独的方法并跳过参数:

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

public static List<string> GetSerializedMyListOfData()

The advantages of this approach is 这种方法的优点是

  1. It's more readable (imo) GetSerializedMyListOfData() vs GetMyListOfData<string>(true) (imo) GetSerializedMyListOfData()GetMyListOfData<string>(true)更具可读性
  2. You also know the intent of the caller at compile time and don't have to throw an exception when the type argument don't match the intent to leave the data serialized 您还知道了调用方在编译时的意图,并且当type参数与意图不匹配而使数据保持序列化时,不必引发异常

You can cast to object first: 您可以先转换为object

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

however a cleaner solution could be to create another method for dealing with strings, this would also allow you to remove the leaveSerialized parameter. 但是,更干净的解决方案是创建另一个处理字符串的方法,这也将允许您删除leaveSerialized参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM