这个名字有点模糊,所以情况如下:
我正在编写代码以使用某些“轨迹”。轨迹是一个抽象的东西,所以我用不同的接口描述它们。所以我有一个代码:
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);
我认为如果我为每个接口子集创建一个整体接口,我就能做到,但它会变得非常难看。
答案 0 :(得分:1)
您可以完全消除ICondition
,只使用谓词和功能样式。以下是制作静态方法的示例: -
public static Predicate<T> CountLessThan<T> (int value) where T:ICount
{
return (T item) => item.Count < value;
}
以下是你如何使用它: -
Predicate<SimpleTrajectory> anded = x => CountLessThan<SimpleTrajectory>(5)(x) && CountLessThan<SimpleTrajectory>(3)(x);
您还可以创建这样的扩展方法来组合谓词: -
public static Predicate<T> And<T>(this Predicate<T> first, Predicate<T> second)
{
return (T item) => first(item) && second(item);
}
另一种方法是拥有一个基本的,抽象的,通用的Condition类,从中推导出其他条件,然后在基本条件类中实现And,或者......允许一个流畅的界面,如: -
... = new CountLessThan(5).And(new CountLessThan(3))
在T中具有通用性将确保您只能组合具有相同T的条件。