10

次のシナリオがあります。

A私には3つのクラスがあり、それらを、、Bと呼びましょうC。それらに共通しているのは、同じインターフェイスから継承し、ISomeInterfaceEntityFrameworkを使用してエンティティにマップされるクラスであるということだけです。

このインターフェイスを実装するオブジェクトのリストを受け取ったメソッドがありますが、オブジェクト自体は、、またはのインスタンスにAなりBますC

メソッドシェルは次のようになります

public void MyMethod(List<ISomeInterface> entityList)
{
  foreach(var entity in entityList)
  {
    ProcessEntity(entity);
  }
}

さて、問題はProcessEntityメソッドにあります。これは一般的なメソッドであり、タイプまたはエンティティに応じてデータベースから一致する要素のテーブルを取得する必要があるため、次のようになります。

public void ProcessEntity<T>(T entity)
{
  using( var repository = new DbRepository())
  {
    var set = repository.Set<T>();
    ...
  }
}

問題は、この場合は実際のtype(、または)ではなく、行var set = repository.Set<T>();が失敗することTです。そのため、指定された型に関連付けることができない例外が発生します。これは理解できます。ISomeInterfaceABC

だから私の質問は:リスト内のオブジェクトの実際のタイプでProcessEntityを呼び出すにはどうすればよいですか?それらが実装するインターフェイスタイプではありません。

4

3 に答える 3

14

dynamicエンティティを ProcessEntity に渡すときにキーワードを適用できます。この場合、エンティティの実際のタイプは実行時に決定されます。

public void MyMethod(List<ISomeInterface> entityList)
{
  foreach(var entity in entityList)
  {
    dynamic obj = entity;
    ProcessEntity(obj);
  }
}
于 2012-05-31T09:33:59.413 に答える
2

さて、訪問者のようなトリックを実行して、次の回避策を使用できます。

  1. Process(EntityProcessor ep)でメソッドを定義するISomeInterface
  2. Aと同じように (および と で同じep.ProcessEntity<A>(this)方法でB)C実装します。
  3. ループの代わりにProcessEntity(entity)、 を呼び出すだけentity.Process(this)です。

(メソッド名はおそらく最もきれいではありませんが、アイデアを得る必要があります)

于 2012-05-31T09:38:52.297 に答える
2

リフレクションを使用して汎用メソッド定義を取得し、それを呼び出すことができます。次に例を示します。

var method = typeof(ClassContainingProcessEntity)
    .GetMethod(ProcessEntity)
    .MakeGenericMethod(entity.GetType);
method.Invoke(this, entity);

メソッドをタイプごとにキャッシュし、パフォーマンスが重要な場合は、ある種のデリゲート ファクトリを使用して実行時にコンパイルできます。

または、訪問者パターンを使用することもできます

于 2012-05-31T09:39:58.507 に答える