3

次のように、関連するクラスのさまざまなグループを実装しようとしています。

  • MySQLデータベース
  • MySQLTable (MySQLDatabase を参照)
  • MySQLRecord (MySQLTable を参照)
  • PostGreデータベース
  • PostGreTable (PostGreDatabase を参照)
  • PostGreRecord (PostGreTable を参照)
  • Oracleデータベース
  • ...

相対クラス (MySQLTable、PostGreTable など) には多くの共有コードがあるため、次のように、抽象親クラスとジェネリックを使用してこれを実装しました。

class Database {}

class Table<DatabaseType> where DatabaseType : Database 
{
  public DatabaseType FDatabase; //this is what I mean by "references"
}

class Record<TableType, DatabaseType> where 
  DatabaseType : Database
  TableType : Table<DatabaseType> 
{
  public TableType FTable;
}

class MySQLDatabase : Database {}

class MySQLTable : Table<MySQLDatabase> 
{
  public string FCharset;
}

MySQLRecord : Record<MySQLTable, MySQLDatabase> {}

...

そして、このアーキテクチャで次のことができるようにする必要があります。

  • 間違った参照を防ぎます。

例: MySQLTable は PostGreDatabase または OracleDatabase を参照できません。MySQLDatabase のみを参照できます。

  • プログラマーがキャストを必要とせずにオブジェクト固有のプロパティにアクセスできるようにします。

例:

SomeMySQLRecord.FTable.FCharset = 'UTF-8'; 

それ以外の

((MySQLTable)SomeMySQLRecord.FTable).Charset = 'UTF-8'; 

クラスの実際のグループには3つ以上のクラスがあり、ジェネリックが実際にコードを忍び寄っているため、これを行うためのよりエレガントな方法(またはパターン)を探しています。例:

MyType : Type1<GType1, GType2, GType3, GType4> where
  GType1 : Type2,
  GType2 : Type3<GType1>,
  GType3 : Type4<GType1, GType2>,
  GType4 : Type5<GType2, GType1, Type2, GType3>
4

2 に答える 2

0

私にとってジェネリックはここでは意味がありません。独自のコードを取る:

Table<DatabaseType : Database>
MySQLTable : Table<MySQLDatabase>

MySQLTableは、Tableの子として定義しているため、ジェネリックを使用して定義されていると想定します。

MySQLTable<Something> : Table<MySQLDatabase>

ここで何かをどのように定義しますか?それは意味がありません。

これを達成するためにジェネリックを使用している場合:

例:MySQLTableはPostGreDatabaseまたはOracleDatabaseを参照できず、MySQLDatabaseのみを参照できます。

それがジェネリックスを使用するための必要十分条件ではないと思います。

于 2013-01-02T07:20:41.843 に答える
0

私は少し異なるルートを取りますが、それがあなたの特定のケースでうまくいくかどうかは完全にはわかりません:

     public class Provider { }

    public class Oracle : Provider { }

    public class AbstractDatabase<T> where T : Provider
    {
        // Your base code here
    }

    public class AbstractTable<T> where T : Provider
    {
        public AbstractDatabase<T> FDatabase { get; set; }
        // Your base code here
    }

    public class AbstractRecord<T> where T : Provider
    {
        public AbstractTable<T> FTable { get; set; }
    }

    public class OracleDatabase : AbstractDatabase<Oracle> { }

    public class OracleTable : AbstractTable<Oracle>
    {
        public new OracleDatabase FDatabase { get; set; }

        // Your strongly typed code
        public OracleTable(OracleDatabase parent) { }
    }
于 2013-01-04T03:58:33.483 に答える