Jas*_*ner 1 c# generics polymorphism
我有一个函数,它接受一个序列化的字符串,打破字符串以构建它定义的许多对象,然后返回一个通用列表.这是函数,它正如我需要的那样工作:
// '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();
}
Run Code Online (Sandbox Code Playgroud)
由于缺乏更好的单词,我试图做一些"反向多态"而没有明确地比较每个支持的类型'T'.例如,我想做到这一点,而不是if,else if,...:
// Create a new object and then convert it to the generic type T.
// Then cast it back to the base object so we can access the deserialize method.
var item = (BaseObject)Convert.ChangeType(new BaseObject(), typeof(T));
item.BuildFromSerializedValue(serializedItem);
data.Add((T)Convert.ChangeType(item, typeof(T)));
Run Code Online (Sandbox Code Playgroud)
当然这不起作用,因为新的BaseObject不能被"转发"到继承的类.
我试过让函数返回一个BaseObjects 数组:
internal static BaseObject[] DeserializeData(string serializedData)
Run Code Online (Sandbox Code Playgroud)
但是当我将返回值合并到List<BaseObjectSpecific1>(等)时,这不起作用
我觉得我错过了一些东西,或者说这比想要的更复杂.有没有一种方法可以支持任何类型的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();
}
Run Code Online (Sandbox Code Playgroud)
这样,编译器已经知道每个T都是从BaseObject(因此具有该BuildFromSerializedValue()方法)派生的.并且,通过使用new()约束,它还知道可以创建新的实例,T因为它具有无参数构造函数.
此外,您不再需要显式转换item为,T因为编译器已经知道它是 a T.
更多关于MSDN
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |