Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C#泛型来支持特定的类型,而无需硬编码类型比较_C#_Generics_Polymorphism - Fatal编程技术网

使用C#泛型来支持特定的类型,而无需硬编码类型比较

使用C#泛型来支持特定的类型,而无需硬编码类型比较,c#,generics,polymorphism,C#,Generics,Polymorphism,我有一个函数,它接收一个序列化的字符串,将该字符串拆分以构建它定义的任意多个对象,然后返回一个通用列表。这是函数,它正按照我的需要工作: // 'T' only supports specific types - those derived from BaseObject. internal static T[] DeserializeData<T>(string serializedData) { var data = new List<T>(); /

我有一个函数,它接收一个序列化的字符串,将该字符串拆分以构建它定义的任意多个对象,然后返回一个通用列表。这是函数,它正按照我的需要工作:

// 'T' only supports specific types - those derived from BaseObject.
internal static T[] DeserializeData<T>(string serializedData)
{
    var data = new List<T>();

    // Break into individual serialized items and decode each.
    foreach (var serializedItem in (serializedData ?? "").Split(','))
    {
        // Skip empty entries.
        if (serializedItem == "")
        {
            continue;
        }

        // Base class which 'T' will always be derived from.
        BaseObject item = null;

        // Initialize object based on the generic type provided.
        if (typeof(T) == typeof(BaseObjectSpecific1))
        {
            item = new BaseObjectSpecific1();
        }
        else if (typeof(T) == typeof(BaseObjectSpecific2))
        {
            item = new BaseObjectSpecific2();
        }
        // Add additional checks for BaseObjectSpecific3, etc.


        item.BuildFromSerializedValue(serializedItem);

        data.Add((T)Convert.ChangeType(item, typeof(T)));
    }

    return data.ToArray();
}
当然,这不起作用,因为新的
BaseObject
不能“向前”转换到继承的类

我已尝试让函数返回
BaseObject
s的数组:

internal static BaseObject[] DeserializeData(string serializedData)
但是,当我将返回值合并到
列表中时,这不起作用

我觉得我遗漏了什么,或者让事情变得比要求的更复杂。有没有一种方法可以支持使用泛型的任何类型的
BaseObject
,而不必显式地将T与每个继承的类类型进行比较?

您可以简单地与
new()
约束一起使用:

internal static T[] DeserializeData<T>(string serializedData)
     where T : BaseObject, new()
{
    var data = new List<T>();

    // Break into individual serialized items and decode each.
    foreach (var serializedItem in (serializedData ?? "").Split(','))
    {
        // Skip empty entries.
        if (serializedItem == "")
            continue;

        T item = new T();

        // Add additional checks for BaseObjectSpecific3, etc.

        item.BuildFromSerializedValue(serializedItem);

        data.Add(item);
    }

    return data.ToArray();
}
内部静态T[]反序列化数据(字符串序列化数据)
其中T:BaseObject,new()
{
var data=新列表();
//分解成单独的序列化项并对每个项进行解码。
foreach(var serializedItem in(serializedData???).Split(','))
{
//跳过空条目。
如果(serializedItem==“”)
继续;
T项=新的T();
//添加BaseObjectSpecific3等的附加检查。
item.BuildFromSerializedValue(serializedItem);
数据。添加(项目);
}
返回data.ToArray();
}
通过这种方式,编译器已经知道每个
T
都是从
BaseObject
派生的(因此具有
BuildFromSerializedValue()
方法)。而且,通过使用
new()
约束,它还知道可以创建
T
的新实例,因为它有一个无参数构造函数

此外,您不再需要显式地将
强制转换为
T
,因为编译器已经知道它是
T

有关

的详细信息,您可以简单地与
new()
约束一起使用:

internal static T[] DeserializeData<T>(string serializedData)
     where T : BaseObject, new()
{
    var data = new List<T>();

    // Break into individual serialized items and decode each.
    foreach (var serializedItem in (serializedData ?? "").Split(','))
    {
        // Skip empty entries.
        if (serializedItem == "")
            continue;

        T item = new T();

        // Add additional checks for BaseObjectSpecific3, etc.

        item.BuildFromSerializedValue(serializedItem);

        data.Add(item);
    }

    return data.ToArray();
}
内部静态T[]反序列化数据(字符串序列化数据)
其中T:BaseObject,new()
{
var data=新列表();
//分解成单独的序列化项并对每个项进行解码。
foreach(var serializedItem in(serializedData???).Split(','))
{
//跳过空条目。
如果(serializedItem==“”)
继续;
T项=新的T();
//添加BaseObjectSpecific3等的附加检查。
item.BuildFromSerializedValue(serializedItem);
数据。添加(项目);
}
返回data.ToArray();
}
通过这种方式,编译器已经知道每个
T
都是从
BaseObject
派生的(因此具有
BuildFromSerializedValue()
方法)。而且,通过使用
new()
约束,它还知道可以创建
T
的新实例,因为它有一个无参数构造函数

此外,您不再需要显式地将
强制转换为
T
,因为编译器已经知道它是
T


更多关于

完美的信息。我知道我错过了一些简单的事情。谢谢你的帮助。太好了。我知道我错过了一些简单的事情。谢谢你在这方面的帮助。