Ric*_* Fu 5 c# inheritance abstract-class type-conversion type-parameter
我有一个基本抽象类及其抽象类型参数:
public abstract class Database<T> where T : DatabaseItem, new() {
protected List<T> _items = new List<T> ();
protected virtual void Read (string[] cols) {
T item = new T ();
...
}
public abstract class DatabaseItem {
...
}
Run Code Online (Sandbox Code Playgroud)
然后我有许多固有的儿童课程:
public class ShopDatabase : Database<ShopItem> {}
public class ShopItem : DatabaseItem {}
public class WeaponDatabase : Database<WeaponItem> {}
public class WeaponItem : DatabaseItem {}
...
Run Code Online (Sandbox Code Playgroud)
现在,我想使用Dictionary来跟踪数据库以及使用DatabaseItem类型返回它们的方法,如下所示:
Dictionary<Type, Database<DatabaseItem>> databases;
public static Database<T> GetDatabase<T> () where T: DatabaseItem {
return databasebases [typeof (T)];
}
Run Code Online (Sandbox Code Playgroud)
然后它给了我"'T'必须是一个非抽象类型,带有一个公共无参数构造函数,以便将它用作参数'T'"错误,因为DatabaseItem是抽象的.我将DatabaseItem设置为非抽象类型,错误消失但仍然出现了很多类型转换错误...
发现了类似的问题,但我还是不明白......
实现这一目标的更好的解决方案/结构是什么?
最简单的方法是将Database<T>
后代存储为对象:
static class DatabaseManager
{
private static Dictionary<Type, object> databases = new Dictionary<Type, object>();
// ....
public static Database<T> GetDatabase<T>()
where T : DatabaseItem, new()
{
return (Database<T>)databases[typeof(T)];
}
}
Run Code Online (Sandbox Code Playgroud)
即使您转向DatabaseItem
具有无参数构造函数的非抽象类,这也无济于事,因为typeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)
.
请注意,GetDatabase<T>
方法的通用约束必须与类的通用约束相同Database<T>
。
更新。
有没有办法知道类使用什么类型参数?例如给ShopDatabase,我想得到ShopItem。我在初始化数据库字典时需要它
使用反射:
var databaseItemType = typeof(ShopDatabase).BaseType.GetGenericArguments()[0];
Run Code Online (Sandbox Code Playgroud)
对于这样的情况:
class FooDatabase : Database<FooItem> {}
class BooDatabase : FooDatabase {}
// etc...
Run Code Online (Sandbox Code Playgroud)
您需要循环遍历继承树才能找到Database<FooItem>
.