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
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.
© Stack Overflow or respective owner