使用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
更多关于完美的信息。我知道我错过了一些简单的事情。谢谢你的帮助。太好了。我知道我错过了一些简单的事情。谢谢你在这方面的帮助。