这对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>>'.
答案 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);
}
}