5

取り扱い抽象クラスから固有のクラスやタイプパラメータ

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

... 

ここで辞書を入れて、DatabaseItemタイプのようなものを使用してデータベースを返す方法と、

Dictionary<Type, Database<DatabaseItem>> databases; 

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

そして、それは私に与えたDatabaseItemが抽象的であるため、エラー「『T』のパラメータとして 『T』を、それを使用するために、公共のパラメータなしのコンストラクタを持つ非抽象型でなければなりません」。私はより良い何

...

が同様questionが見つかりましたが、私はまだ理解していない...エラーがなくなって、それでも型変換エラーがたくさん出てきている、非抽象型としてDatabaseItemを作りましたこれを達成するためのソリューション/構造?

+0

おそらくあなたDatabaseクラスのためのインタフェース、例えば 辞書を定義するには、<タイプ、するIDatabase> –

答えて

3

最も簡単なのは、オブジェクトとして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を回していてもパラメータなしのコンストラクタを持つ-abstractクラスですが、typeof(Database<ShopItem>) != typeof(Database<DatabaseItem>)のためにこれも役に立ちません。

GetDatabase<T>メソッドのジェネリック制約は、Database<T>クラスと同じでなければならないことに注意してください。

更新

クラスが使用するパラメータの型を知る方法はありますか?例えば ShopDatabase、ShopItemを取得します。あなたがDatabase<FooItem>を見つけるために、継承ツリーをループする必要があります

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

:このような場合のために

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

:私は反射 データベース辞書

使用を初期化するとき、私はそれを必要とします。

+0

私はほとんどそこに我々考えて、クラスが使用してどのような種類のパラメータを知る方法はありますか?例: ShopDatabaseを与えて、私はShopItemを取得したい。 *データベース*辞書を初期化するときに必要です –

+0

@RichardFu:答えを更新しました。 – Dennis

1

悪いニュースは、キャストの種類なしでコードを使用できないことです。その後、このコードを使用して、データベースの非ジェネリック型またはinerfaceを定義します。あなたが行うことができます

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