I have a base abstract class and its abstract type parameter as:
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 {
...
}
Then I have number of children classes inherent from it:
public class ShopDatabase : Database<ShopItem> {}
public class ShopItem : DatabaseItem {}
public class WeaponDatabase : Database<WeaponItem> {}
public class WeaponItem : DatabaseItem {}
...
Now, I want to put a Dictionary to keep track of the databases and a method to return them using DatabaseItem type, something like this:
Dictionary<Type, Database<DatabaseItem>> databases;
public static Database<T> GetDatabase<T> () where T: DatabaseItem {
return databasebases [typeof (T)];
}
Then it gave me "'T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T'" error because DatabaseItem is abstract. I made DatabaseItem as non-abstract type, the error is gone but still lot of type conversion errors came out...
Found a similar question but I still not understand...
What's the better solution/structure to achieve this?
The bad news is that you can't use your code without kind of cast. Define a non-generic type or inerface for database, then use this code:
The simplest you can do is to store
Database<T>
descendants as objects:Even if you turn
DatabaseItem
to non-abstract class with parameterless constructor, this won't help either, becausetypeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)
.Note, that generic constraints for
GetDatabase<T>
method must be the same as forDatabase<T>
class.Upd.
Use reflection:
For cases like this:
you'll need to loop through inheritance tree to find
Database<FooItem>
.