Название немного размыто, поэтому вот ситуация:
Я пишу код для использования некоторых «траекторий». Траектории - абстрактная вещь, поэтому я описываю их с помощью различных интерфейсов. Итак, у меня есть такой код:
namespace Trajectories {
public interface IInitial<Atom>
{
Atom Initial { get; set; }
}
public interface ICurrent<Atom>
{
Atom Current { get; set; }
}
public interface IPrevious<Atom>
{
Atom Previous { get; set; }
}
public interface ICount<Atom>
{
int Count { get; }
}
public interface IManualCount<Atom> : ICount<Atom>
{
int Count { get; set; }
}
...
}
Каждая конкретная реализация траектории будет реализовывать некоторые из вышеуказанных интерфейсов.
Вот конкретная реализация траектории:
public class SimpleTrajectory<Atom> : IInitial<Atom>, ICurrent<Atom>, ICount<Atom> {
// ICount
public int Count { get; private set; }
// IInitial
private Atom initial;
public Atom Initial { get { return initial; } set { initial = current = value; Count = 1; } }
// ICurrent
private Atom current;
public Atom Current { get { return current; } set { current = value; Count++; } }
}
Теперь я хочу иметь возможность делать выводы о траекториях, поэтому, например, я хочу поддержать предикаты о различных свойствах некоторой траектории:
namespace Conditions
{
public interface ICondition<Atom, Trajectory>
{
bool Test(ref Trajectory t);
}
public class CountLessThan<Atom, Trajectory> : ICondition<Atom, Trajectory>
where Trajectory : Trajectories.ICount<Atom>
{
public int Value { get; set; }
public CountLessThan() { }
public bool Test(ref Trajectory t)
{
return t.Count < Value;
}
}
public class CurrentNormLessThan<Trajectory> : ICondition<Complex, Trajectory>
where Trajectory : Trajectories.ICurrent<Complex>
{
public double Value { get; set; }
public CurrentNormLessThan() { }
public bool Test(ref Trajectory t)
{
return t.Current.Norm() < Value;
}
}
}
Теперь возникает вопрос: что, если я хочу реализовать предикат AND?
Это было бы что-то вроде этого:
public class And<Atom, CondA, TrajectoryA, CondB, TrajectoryB, Trajectory> : ICondition<Atom, Trajectory>
where CondA : ICondition<Atom, TrajectoryA>
where TrajectoryA : // Some interfaces
where CondB : ICondition<Atom, TrajectoryB>
where TrajectoryB : // Some interfaces
where Trajectory : // MUST IMPLEMENT THE INTERFACES FOR TrajectoryA AND THE INTERFACES FOR TrajectoryB
{
public CondA A { get; set; }
public CondB B { get; set; }
public bool Test(ref Trajectory t) {
return A.Test(t) && B.Test(t);
}
}
Как я могу сказать: поддерживать только эти траектории, для которых аргументы AND в порядке?
Так что я могу написать:
var vand = new CountLessThan(32) & new CurrentNormLessThan(4.0);
Я думаю, что если бы я создал общий интерфейс для каждого подмножества интерфейсов, я мог бы это сделать, но это станет довольно уродливо.