Can I constrain a template parameter class to implement the interfaces that are supported by other?
- by K. Georgiev
The name is a little blurry, so here's the situation:
I'm writing code to use some 'trajectories'. The trajectories are an abstract thing, so I describe them with different interfaces. So I have a code as this:
    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; }
        }
        ...
    }
Every concrete implementation of a trajectory will implement some of the above interfaces.
Here's a concrete implementation of a trajectory:
        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++; } }
        }
Now, I want to be able to deduce things about the trajectories, so, for example I want to support predicates about different properties of some trajectory:
    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;
        }
    }
}
Now, here's the question: What if I wanted to implement AND predicate? 
It would be something like this:
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);
}
}
How can I say: support only these trajectories, for which the arguments of AND are ok?
So I can be able to write:
var vand = new CountLessThan(32) & new CurrentNormLessThan(4.0);
I think if I create an orevall interface for every subset of interfaces, I could be able to do it, but it will become quite ugly.