1

データベースにアクセスするためのいくつかの異なる方法をインターフェースするインターフェース IDatabase があります。たとえば、RESTful または MySqlDirectConnect を使用します。

次に、データベースからデータを取り出す必要があるメンバー変数 A、B、C を持つクラス foo があります。

public class foo
{
    private string a;
    private int b;
    private int c;
}

最初は、すべてのメンバー変数に対して Get メソッドを作成するつもりでした。Generics を使用して、使用するインターフェイスを指定します。

public string GetA<T>() where T: IDatabase
{
   //example might be GetA<RESTful>();
}

public int GetB<T>() where T: IDatabase
{
   //example might be GetB<MySQL>();
}

等々....

私が見る問題は、データベースが変更された場合、戻ってこれらすべてのメソッドを変更する必要があることです。場合によっては、クラス foo に約 20 個の変数があり、それぞれに Get() メソッドが含まれていることがあります。

そこで、照会したいインターフェイスと変数の両方を指定できる、本当に汎用的な GetValue() を作成したいと思います。

次の行に沿ったもの:

public object GetValue<T>(the class variable I want to query) where T: IDatabase
{
    //query database using type T and return it to the variable specified
}

メソッド内のすべてのメンバー変数に条件を付けることは避けたいと思います。

それで、これは可能ですか?

4

3 に答える 3

1

ジェネリックは、ここではまったく適していないようです。、などIDatabaseの複数の実装を持つインターフェース(あなたが持っているように)が必要です。RestfulDbMySqlDb

次に、IDatabase に method:object GetValue(string name)を含めることができ、 から派生した各クラスでこれの具体的な実装を提供しますIDatabase

ジェネリックを使用している場合、コードはどのようGetValue<T>にしてMySqlデータベースのどのインスタンスを追跡したいかを知ることができます.それが持っているのは型だけです.

NHibernat eのようなプロジェクトがこれにどのように対処しているかを調べてみてください。

于 2012-08-26T16:56:28.297 に答える
0

これが私が考え出した素晴らしい解決策です

public void GetValue<T>(string property) where T: IDatabase, new()
{
    IDatabase database = new T();
    database.RegisterObserver(this);

    string FROM = typeof(theCurrentClass).Name;
    string SELECT = editProperty = property;
    string WHERE = "1";

    database.Select(new Query(SELECT, FROM, WHERE));        
}

private string fieldName;  //contains the name of the field I want to edit

void IObserver.Update(object data)
{       
    FieldInfo field = this.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);

    if(field != null)
    {
        field.SetValue(this, data);         
    }
}

編集:私は最終的にそれを理解しました、ちょうど最終的な答えで上記のコードを更新しました

于 2012-08-26T20:13:56.473 に答える
0

インターフェイスを宣言します:

public interface IDataProvider<T>
{
    T Get()
}

次に、データ ソースとクラス タイプごとに 1 つのプロバイダーを実装します。

public class FootRestProvider : IDataProvider<Foo>
{
    public Foo Get()
    {
        // implement logic to get foos from rest
     }
}

public class FooMySqlProvider : IDataProvider<Foo>
{
    public Foo Get()
    {
        // implement logic to get foos from mysql
    }
}   

最後に、Foo のプロパティが異なるソースからのものである場合。それらを別のクラスにマージします:

public class FooMerger
{
    // fill this list from constructor
    private IList<IDataProvider<Foo>> providers;

    public Foo Get()
    {
        var foosToMerge = providers.Select( x => x.Get() ).

        // implement merging logic here 
    }
}
于 2012-08-26T16:57:24.653 に答える