如何绕过ref参数不允许类型变化?

时间:2011-01-06 14:07:47

标签: c# class-design covariance contravariance variance

假设我的数据访问层中有以下类结构:

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 parameters don't allow type variation。我正在努力寻找一种方法来实现这种功能,同时保持类型安全性和接口的逆变性。任何想法都表示赞赏。

2 个答案:

答案 0 :(得分:1)

不确定这是否适用于您的确切上下文,但您是否尝试过将ApplyFolders设为通用?

void ApplyFolders<TEnum>(ref IEnumerable<TEnum> models) where TEnum : T;

答案 1 :(得分:1)

我会看一下Ptr class。我最近一直在利用这个课程来完全破坏.NET对ref关键字的所有限制,让我因为某种原因让我对CLR产生副作用感觉我没有权利。