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

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”必须是具有公共(public)无参数构造函数的非抽象类型,才能将其用作参数“T”。错误。我将DatabaseItem设为非抽象类型,该错误消失了,但是仍然出现了很多类型转换错误...

找到了类似的question,但我还是不明白...

有什么更好的解决方案/结构来实现这一目标?

最佳答案

最简单的方法是将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>类相同。

更新



使用反射:
var databaseItemType = typeof(ShopDatabase).BaseType.GetGenericArguments()[0];

对于这样的情况:
class FooDatabase : Database<FooItem> {}
class BooDatabase : FooDatabase {}
// etc...

您将需要遍历继承树以找到Database<FooItem>

关于c# - 处理类继承自抽象类和类型参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34305723/

10-15 06:03