处理抽象类和类型参数中固有的类

本文关键字:抽象类 类型参数 处理 | 更新日期: 2023-09-27 18:27:08

我有一个基本抽象类及其抽象类型参数为:

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 {
  ...
}

然后我就有了一些固有的儿童课程:

public class ShopDatabase : Database<ShopItem> {}
public class ShopItem : DatabaseItem {}
public class WeaponDatabase : Database<WeaponItem> {}
public class WeaponItem : DatabaseItem {}
...

现在,我想放一个Dictionary来跟踪数据库,并使用DatabaseItem类型返回它们的方法,类似于以下内容:

Dictionary<Type, Database<DatabaseItem>> databases;
public static Database<T> GetDatabase<T> () where T: DatabaseItem {
  return databasebases [typeof (T)];
}

然后它给了我"'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)];
    }
}

即使将DatabaseItem转换为具有无参数构造函数的非抽象类,这也无济于事,因为typeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)

注意,GetDatabase<T>方法的通用约束必须与Database<T>类的约束相同。

上升

有没有办法知道一个类使用什么类型的参数?例如给予ShopDatabase,我想获取ShopItem。初始化时需要它数据库字典

使用反射:

var databaseItemType = typeof(ShopDatabase).BaseType.GetGenericArguments()[0];

对于这样的情况:

class FooDatabase : Database<FooItem> {}
class BooDatabase : FooDatabase {}
// etc...

您需要循环遍历继承树才能找到Database<FooItem>

坏消息是,如果没有强制转换,就无法使用代码。为数据库定义一个非通用类型或接口,然后使用以下代码:

Dictionary<Type, Database> databases;
public static Database<T> GetDatabase<T>() where T: DatabaseItem, new()
{
    return databasebases[typeof(T)] as Database<T>;
}