处理抽象 class 和类型参数固有的 classes
Handling classes inherent from abstract class and type parameter
我有一个基本抽象 class 及其抽象类型参数:
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 {
...
}
然后我有 children class 个固有的数:
public class ShopDatabase : Database<ShopItem> {}
public class ShopItem : DatabaseItem {}
public class WeaponDatabase : Database<WeaponItem> {}
public class WeaponItem : DatabaseItem {}
...
现在,我想放置一个 Dictionary 来跟踪数据库,并使用 DatabaseItem[=32= 来 return 它们的方法] 类型,像这样:
Dictionary<Type, Database<DatabaseItem>> databases;
public static Database<T> GetDatabase<T> () where T: DatabaseItem {
return databasebases [typeof (T)];
}
然后它给了我 "'T' 必须是具有 public 无参数构造函数的 non-abstract 类型才能将其用作参数 'T' “ 错误,因为 DatabaseItem 是抽象的。我将 DatabaseItem 设为 non-abstract 类型,错误消失了,但仍然出现了很多类型转换错误...
找到了类似的question但是还是没看懂...
什么是更好的solution/structure来实现这个目标?
坏消息是你不能在没有转换的情况下使用你的代码。为数据库定义一个非泛型类型或接口,然后使用此代码:
Dictionary<Type, Database> databases;
public static Database<T> GetDatabase<T>() where T: DatabaseItem, new()
{
return databasebases[typeof(T)] as Database<T>;
}
最简单的方法是将 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)];
}
}
即使您使用无参数构造函数将 DatabaseItem
转换为非抽象 class,这也无济于事,因为 typeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)
.
请注意,GetDatabase<T>
方法的通用约束必须与 Database<T>
class 的通用约束相同。
更新.
is there a way to know what type parameter a class using? e.g. giving
ShopDatabase, I want to get ShopItem. I need it when I initialize
databases dictionary
使用反射:
var databaseItemType = typeof(ShopDatabase).BaseType.GetGenericArguments()[0];
对于这样的情况:
class FooDatabase : Database<FooItem> {}
class BooDatabase : FooDatabase {}
// etc...
您需要遍历继承树才能找到 Database<FooItem>
。
我有一个基本抽象 class 及其抽象类型参数:
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 {
...
}
然后我有 children class 个固有的数:
public class ShopDatabase : Database<ShopItem> {}
public class ShopItem : DatabaseItem {}
public class WeaponDatabase : Database<WeaponItem> {}
public class WeaponItem : DatabaseItem {}
...
现在,我想放置一个 Dictionary 来跟踪数据库,并使用 DatabaseItem[=32= 来 return 它们的方法] 类型,像这样:
Dictionary<Type, Database<DatabaseItem>> databases;
public static Database<T> GetDatabase<T> () where T: DatabaseItem {
return databasebases [typeof (T)];
}
然后它给了我 "'T' 必须是具有 public 无参数构造函数的 non-abstract 类型才能将其用作参数 'T' “ 错误,因为 DatabaseItem 是抽象的。我将 DatabaseItem 设为 non-abstract 类型,错误消失了,但仍然出现了很多类型转换错误...
找到了类似的question但是还是没看懂...
什么是更好的solution/structure来实现这个目标?
坏消息是你不能在没有转换的情况下使用你的代码。为数据库定义一个非泛型类型或接口,然后使用此代码:
Dictionary<Type, Database> databases;
public static Database<T> GetDatabase<T>() where T: DatabaseItem, new()
{
return databasebases[typeof(T)] as Database<T>;
}
最简单的方法是将 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)];
}
}
即使您使用无参数构造函数将 DatabaseItem
转换为非抽象 class,这也无济于事,因为 typeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)
.
请注意,GetDatabase<T>
方法的通用约束必须与 Database<T>
class 的通用约束相同。
更新.
is there a way to know what type parameter a class using? e.g. giving ShopDatabase, I want to get ShopItem. I need it when I initialize databases dictionary
使用反射:
var databaseItemType = typeof(ShopDatabase).BaseType.GetGenericArguments()[0];
对于这样的情况:
class FooDatabase : Database<FooItem> {}
class BooDatabase : FooDatabase {}
// etc...
您需要遍历继承树才能找到 Database<FooItem>
。