Допустим, у меня есть следующий класс структуры в моем слое доступа к данным:Как я могу обойти параметры ref, не допускающие изменения типа?
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()
});
Super.
Но теперь я хочу, чтобы каждое поведение применяло набор LINQ-фильтров к объекту. Моя первая мысль была, чтобы добавить этот метод IBehavior<T>
:
void ApplyFilters<IEnumerable>(ref IEnumerable<T> models)
... в котором реализация поведение будет применяться набор Where
положений к перечислению по своему усмотрению.
Однако, как выясняется, ref parameters don't allow type variation. Я изо всех сил пытаюсь найти способ реализовать такую функциональность, сохраняя при этом безопасность как типа, так и контравариантную природу интерфейса. Любые идеи приветствуются.
Я бы ожидал, что 'ApplyFilters' будет иметь подпись' IEnumerable ApplyFilters (IEnumerable models) ' –
Gabe
Не получилось бы, это делает T тип возврата. Я помню, как пытались оба, и в моем случае использования, использующем ref, имеет смысл. Таким образом, если поведение не хочет применять какие-либо фильтры, оно может просто оставить метод пустым. –