2010-06-06 3 views
1

이름이 약간 흐리므로 상황은 다음과 같습니다.다른 매개 변수가 지원하는 인터페이스를 구현하도록 템플릿 매개 변수 클래스를 제한 할 수 있습니까?

일부 '궤도'를 사용하는 코드를 작성하고 있습니다. 탄도는 추상적 인 것이므로 다른 인터페이스로 설명합니다. 따라서 코드는 다음과 같습니다.

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; } 
    } 
    ... 
} 

궤도의 모든 구체적인 구현은 위 인터페이스 중 일부를 구현합니다.

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 &lt 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() &lt Value; 
     } 
    } 
} 
: 예를 들어 내가 어떤 궤도의 다른 속성에 대한 조건을 지원하고자, 나는 궤적에 대한 일을 추론 할 수 있도록하려면 지금

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++; } } 
    } 

, 그래서 : 여기 궤도의 고정 구현입니다

자, 다음과 같은 질문입니다. 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); 
    } 
} 

어떻게 내가 말할 수 있습니다 만 지원이 궤도,하는의 인수와는 괜찮 니?

var vand = new CountLessThan(32) & new CurrentNormLessThan(4.0); 

내가 인터페이스의 모든 부분 집합에 대한 전반적인 인터페이스를 만들 경우 내 생각은, 내가 그것을 할 수있을 수 있지만, 그것은 아주 추한 될 것입니다 :

그래서 내가 쓸 수 있습니다.

+0

이 조건을 결합 할 수 있도록 할 T에서 일반적이기 때문에, 당신은'ref' 키워드 (사용 참조로 궤도를 보낼 필요가 없습니다) Trajectory가 클래스 (참조 타입) 인 한 – abatishchev

+0

당신은'Trajectory : Trajectories.ICount '을 가지고 있지만 ICount는 일반적인 인터페이스가 아닙니다. 왜 그런가요? –

+0

그것은 일반적인 인터페이스입니다 :'public interface ICount {}'하지만 나는 그렇지 않아야한다고 생각합니다. 존재할 필요가 없으므로 - Atom 형식 매개 변수를 사용하지 않습니다. – abatishchev

답변

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); 
} 

다른 조건은 다른 조건이 파생 된 기본, 추상, 일반 조건 클래스를 갖는 것입니다. 그리고 기본 조건 클래스에서 유창한 interfa를 허용하는 And, Or ...를 구현합니다. CE 같은 : -

... = new CountLessThan(5).And(new CountLessThan(3)) 

만 BTW 같은 T.

+0

하지만 여전히 문제가 있습니다 : CountLessThan 에 T가 필요합니다. ICount, 하지만 CurrentNormLessThan 에는 T : ICurrent가 필요하므로 T가 다릅니다.귀하의 코드는 다음과 같습니다 : 술어 (이 프레디 티브 첫 번째, 술부 초) T1 : ICount 여기서 T2 : ICurrent 여기서 Both : ICount, ICurrent; And는 인터페이스의 통합을 구현하는 클래스 만 받아 들여야하며, 두 개의 인수가 필요합니다. –

+0

'And '두 인터페이스를 모두 구현하는'Both' 클래스가 실제로있는 경우 작동하지만, BothA 또는 BothB와 함께 사용할 수있는 Predicate는 And 술어를 빌드 할 때 언급 한 두 인터페이스를 구현하면 제공됩니다. 권리? 단지 '둘 다'에 묶여 있지 않습니다. 나는 본다 ... –

+0

미안하지만,'And'는 그것에 인터페이스를 가져야하는 것이 아니고, 필요한 것은'T'와 같은 두 개의 술어이다. 결정된. –

관련 문제