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>代わりに指定して、に置き換えint、(ヒープの署名と同じように)TKey制約を追加する必要があります。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 に答える