1

这对 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>>'.
4

3 回答 3

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>并替换intTKey,添加约束TKey : IComparable<TKey>(就像在堆的签名中一样。)

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

于 2010-08-25T15:19:44.750 回答
0

我想如果你更换..

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

..和..

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

..它将按照您的预期工作。

于 2010-08-25T15:14:49.703 回答
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);
    }    
}
于 2010-08-25T15:27:53.467 回答