Can I constrain a template parameter class to implement the interfaces that are supported by other?

Posted by K. Georgiev on Stack Overflow See other posts from Stack Overflow or by K. Georgiev
Published on 2010-06-06T21:20:53Z Indexed on 2010/06/06 21:32 UTC
Read the original article Hit count: 335

Filed under:
|
|

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 &lt Atom, Trajectory &gt
        {
            bool Test(ref Trajectory t);
        }

    public class CountLessThan &lt Atom, Trajectory &gt : ICondition &lt Atom, Trajectory &gt
        where Trajectory : Trajectories.ICount &lt Atom &gt
    {
        public int Value { get; set; }
        public CountLessThan() { }

        public bool Test(ref Trajectory t)
        {
            return t.Count &lt Value;
        }
    }

    public class CurrentNormLessThan &lt Trajectory &gt : ICondition &lt Complex, Trajectory &gt
        where Trajectory : Trajectories.ICurrent &lt Complex &gt
    {
        public double Value { get; set; }
        public CurrentNormLessThan() { }

        public bool Test(ref Trajectory t)
        {
            return t.Current.Norm() &lt Value;
        }
    }
}

Now, here's the question: What if I wanted to implement AND predicate? It would be something like this:


public class And &lt Atom, CondA, TrajectoryA, CondB, TrajectoryB, Trajectory &gt : ICondition &lt Atom, Trajectory &gt
    where CondA : ICondition &lt Atom, TrajectoryA &gt
    where TrajectoryA : // Some interfaces
    where CondB : ICondition &lt Atom, TrajectoryB &gt
    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.

© Stack Overflow or respective owner

Related posts about c#

Related posts about generics