C#Generics:将T插入T:IComparable <t>接口冲突</t>

时间:2010-08-25 14:59:23

标签: c# generics heap where-clause priority-queue

这对C#泛型/设计模式大师来说是一个挑战。

我正在尝试实现一个通用堆,然后是一个使用堆的优先级队列。

我的堆的签名是:

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

我的优先级队列类是:

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

    ...

但是当这样做时,编译器(理所当然地)抱怨ICompareble没有实现ICompareble接口,因此

Heap<IComparable<T>, T> m_heap;

冲突
where TKey : IComparable<TKey>

你能做些什么来解决这个问题?!

完整的编译错误:

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>>'.

3 个答案:

答案 0 :(得分:4)

你的实施非常混乱。在我看来,这就足够了:

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

优先级队列是否应该有通用密钥?如果是,那么您应该指定PriorityQueue<TKey, TValue>并将int替换为TKey,添加TKey : IComparable<TKey>的约束(就像您的堆签名一样。)

基本上,您的优先级队列的定义应该看起来像堆的定义,如果您希望密钥是任何类型,或者相同但未在密钥类型上参数化。

答案 1 :(得分:0)

我想如果你替换..

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

.. ..用

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

..它会在您打算工作时起作用。

答案 2 :(得分:0)

我认为如果依靠IComparer<T>而不是Evaluator<T>代表会更好。在任何情况下,作为您问题的直接答案:

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