2010-08-25 7 views
1

Il s'agit d'un défi pour les génériques C#/modèles de conception. J'essaie d'implémenter un tas générique, puis une file d'attente prioritaire qui utilise le segment de mémoire.C# Génériques: Insertion de T en tant que T: IComparable <T> conflit d'interface

Ma signature de tas est:

class Heap<TKey, TValue> where TKey : IComparable<TKey> 

Ma classe de file d'attente prioritaire est:

public delegate IComparable<T> Evaluator<T>(T item); 

class PriorityQueue<T> : IQueue<T> 
{ 
    Evaluator<T> Evaluate; 
    Heap<IComparable<T>, T> m_heap; 

    public PriorityQueue(Evaluator<T> evaluateFunction) 
    { 
     Evaluate = evaluateFunction; 
     m_heap = new Heap<int, T>(HeapType.MinHeap); 
    } 

    ... 

    public void Insert(T element) 
    { 
     m_heap.Insert(Evaluate(element), element); 
    } 

    ... 

Mais en le faisant, le compilateur (à juste titre) se plaint que ICompareble ne met pas en oeuvre l'interface ICompareble, d'où

Heap<IComparable<T>, T> m_heap; 

conflits avec

where TKey : IComparable<TKey> 

Que pouvez-vous faire pour résoudre ce problème ?!

erreur complète du compilateur:

The type 'System.IComparable<T>' cannot be used as type parameter 'TKey' in the generic type or method 'Heap<TKey,TValue>'. There is no implicit reference conversion from 'System.IComparable<T>' to 'System.IComparable<System.IComparable<T>>'. 
+0

Puisque vous semblez toujours initialiser m_heap comme '' nouveau segment de mémoire , pourquoi ne pas changer votre déclaration HEAP m_heap; '? – kevingessner

+0

Ce ne devrait pas être "où TKey: IComparable "? Si je ne me trompe pas, c'est ce qu'évaluera le retour. – Bubblewrap

Répondre

3

Votre implémentation est plutôt confuse. Il me semble que c'est suffisant:

// replaces existing Evaluator signature. I would personally ditch this 
// definition and just use Func<TValue, TKey> instead 
public delegate TKey Evaluator<TKey, TValue>(TValue item); 

class PriorityQueue<T> 
{ 
    Evaluator<int, T> Evaluate; 
    Heap<int, T> m_heap; 

    public PriorityQueue(Evaluator<int, T> evaluateFunction) 
    { 
     Evaluate = evaluateFunction; 
     m_heap = new Heap<int, T>(HeapType.MinHeap); 
    } 

    public void Insert(T element) 
    { 
     m_heap.Insert(Evaluate(element), element); 
    } 
} 

Y a-t-il une raison pour laquelle la file d'attente prioritaire devrait avoir une clé générique? Si oui, alors vous devez spécifier PriorityQueue<TKey, TValue> au lieu et remplacer int avec TKey, en ajoutant la contrainte que TKey : IComparable<TKey> (comme dans la signature de votre tas.)

Fondamentalement, la définition de la file d'attente de priorité devrait soit ressembler à la définition de votre tas, si vous voulez la clé pour être de n'importe quel type, ou la même mais non paramétrée sur le type de clé.

0

Je pense que si vous remplacez ..

class Heap<TKey, TValue> where TKey : IComparable<TKey> 

..avec ..

class Heap<TKey, TValue> where TKey : IComparable<TValue> 

..il fonctionnera comme vous le souhaitez pour travailler.

+0

Pourquoi pensez-vous qu'il voudrait que ses clés Heap implémentent IComparable sur le type TValue? –

+0

Parce que c'est ce que le délégué Evaluator renvoie et est apparemment utilisé comme une clé par la méthode Insert. – Bubblewrap

0

Je pense que ce serait beaucoup mieux si vous comptez sur un IComparer<T> plutôt que votre délégué Evaluator<T>. Dans tous les cas, comme une réponse directe à votre question:

class Heap<TKey, TValue> where TKey : IComparable<TKey> { } 

public delegate TOutput Evaluator<TInput, TOutput>(TInput item) where TOutput : IComparable<TOutput>; 

class PriorityQueue<TInput, TTransformComparable> where TTransformComparable : IComparable<TTransformComparable> 
{ 
    Evaluator<TInput, TTransformComparable> Evaluate; 
    Heap<TTransformComparable, TInput> m_heap; 

    public PriorityQueue(Evaluator<TInput, TTransformComparable> evaluateFunction) 
    { 
     Evaluate = evaluateFunction; 
     m_heap = new Heap<TTransformComparable, TInput>(HeapType.MinHeap); 
    }  

    public void Insert(TInput element) 
    { 
     m_heap.Insert(Evaluate(element), element); 
    }  
} 
Questions connexes