1

データアクセス層に次のクラス構造があるとします。

interface IBehavior<in T>
{
  void Load(T model);
}

class ModelManager<T>
{
  ModelManager(IEnumerable<IBehavior<T>> behaviors) { ... }

  void Load(T model)
  {
    foreach (var behavior in behaviors) {
      behavior.Load(model)
    }
  }
}

これにより、モデルで実装できるさまざまなインターフェイスと、それらのインターフェイスを処理する再利用可能な動作を使用できます。

interface IUnique { ... }
class UniqueBehavior : IBehavior<IUnique>  { ... }

interface ITimestampable  { ... }
class TimestampableBehavior : IBehavior<ITimestampable> { ... }

そして、マネージャーは、の共変性のためにこれらを喜んで受け取りますIBehavior<T>

class MyModel : IUnique, ITimestampable { ... }

new ModelManager<MyModel>(new IBehavior<MyModel>[] {
  new UniqueBehavior(),
  new TimestampableBehavior()
});

素晴らしい。

しかし、ここで、各動作に一連のLINQフィルターをエンティティにも適用させたいと思います。私の最初のアイデアは、このメソッドをIBehavior<T>次のように追加することでした。

void ApplyFilters<IEnumerable>(ref IEnumerable<T> models)

...実装動作はWhere、その裁量で列挙に一連の句を適用します。

ただし、結局のところ、refパラメーターでは型のバリエーションは許可されていません。型の安全性とインターフェースの反変の性質の両方を維持しながら、この種の機能を実装する方法を見つけるのに苦労しています。どんなアイデアでも大歓迎です。

4

2 に答える 2

1

Ptr クラスを見てみましょう。私は最近、このクラスを利用して、.NET が ref キーワードに課すすべての制限を完全に打ち破り、何らかの理由で CLR が自分には権利がないと感じているオブジェクトに副作用を与えられるようにしています。

于 2011-01-06T15:24:43.137 に答える
1

これが正確なコンテキストで機能するかどうかはわかりませんが、ApplyFolders 自体をジェネリックにしてみましたか?

void ApplyFolders<TEnum>(ref IEnumerable<TEnum> models) where TEnum : T;
于 2011-01-06T15:14:34.183 に答える