5

次のクラス宣言の何が問題なのか、誰か説明してもらえますか?

private class PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType> :
        IComparer<PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType>>
            where TPriorityValue : IComparable
            where IIdentifiableEntry : Identifier<IType>
    {
        public TPriorityValue Priority{get;private set;}
        public IIdentifiableEntry Entry{get;private set;}

        public PriorityQueueEntry(TPriorityValue val,IIdentifiableEntry entry)
        {
            Priority = val;
            Entry = entry;
        }
        public int Compare(PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType> first, PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType> second) 
        {
            if (first.Priority.CompareTo(second.Priority) < 0)
            {
                return -1;
            }
            else if (first.Priority.CompareTo(second.Priority) > 0)
            {
                return 1;
            }
            return EqualityComparer<IIdentifiableEntry>.Default.Equals( first.Entry.Id, second.Entry.Id);
        }
    }

EqualityComparer を使用している行でコンパイラが不平を言っています。エラーは次のとおりです。

エラー CS0176: 静的メンバー `object.Equals(object, object)' はインスタンス参照ではアクセスできません。代わりに型名で修飾してください

インスタンス参照を使用している場所がわかりません。


すみません、私のせいです。不完全な質問を投稿しました。完全を期すために、 Identifier クラスは次のとおりです。

public interface Identifier<ID_TYPE> 
{
    ID_TYPE Id{get;set;}
}

そこで EqualityComparer を使用したのは、コピー アンド ペーストのミスが原因でした (申し訳ありませんが、今日は一般的なコードが多すぎます)。

もちろん、私の質問は間違っていました。回答に必要なすべての要素を提供していなかったからです (すぐに削除します)。私はする必要ITypeがありIConvertibleました。とにかくみんなに感謝します。

4

3 に答える 3

6

これはインスタンス リファレンスです。

EqualityComparer<IIdentifiableEntry>.Default

最初の問題は、まったく電話したくobject.Equals(object, object)ないということです。あなたは本当に等値比較器でメソッドを呼び出したいのですが、に変換できない引数でそれを呼び出そうとしていますIIdentifieableEntry

2 番目の問題は、等式比較ではなく順序比較を実行しようとしているため、 ではなくが必要なことです。Comparer<T>EqualityComparer<T>

何を達成しようとしているのかは明確ではありませんが、このコードは少なくともコンパイルされます:

return Comparer<IIdentifiableEntry>.Default.Compare(first.Entry, second.Entry);

本当に Id プロパティを比較したい場合は、ID プロパティ タイプの等値比較子が必要です。そのタイプが何であるかはわかりません。

私はあなたが本当にこのようなものを望んでいる可能性が高いと思います:

return Comparer<string>.Default.Compare(first.Entry.Id, second.Entry.Id);

...しかし、それはの種類によって異なりますId

于 2012-11-13T12:48:36.373 に答える
3

Identifier も EqualityComparer の宣言も示していません。ただし、行を次のように変更する必要があると思います。

return EqualityComparer<IIdentifiableEntry>.Default.Equals<IType>( first.Entry.Id, second.Entry.Id);

[編集]

ジョンさんのコメント通り。等値比較器はまったく必要ありません。その Entry.Id が IComparable であると仮定すると、次のようになります。

return first.Entry.Id.CompareTo(second.Entry.Id);

Entry を IComparable に制限することをお勧めします。したがって、次のようになります。

class PriorityQueueEntry> where TPriorityValue : IComparable where TEntry : IComparable { public TPriorityValue Priority{get;private set;} public TEntry Entry{get;private set;}

    public PriorityQueueEntry(TPriorityValue val, TIdentifiableEntry entry)
    {
        Priority = val;
        Entry = entry;
    }
    public int Compare(PriorityQueueEntry<TPriorityValue, TEntry first, PriorityQueueEntry<TPriorityValue, TEntry> second) 
    {
        if (first.Priority.CompareTo(second.Priority) < 0)
        {
            return -1;
        }
        else if (first.Priority.CompareTo(second.Priority) > 0)
        {
            return 1;
        }
        return first.Enrtry.CompareTo(second.Entry);
    }
}

TEntry がクラスの場合は、いくつかの null チェックを追加することができます。

于 2012-11-13T12:56:46.750 に答える
1

最後に、私はこの方法で解決しました:

private class PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType> :
        IComparer<PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType>>
            where TPriorityValue : IComparable
            where IIdentifiableEntry : Identifier<IType>
            where IType : IConvertible
    {
        public TPriorityValue Priority{get;private set;}
        public IIdentifiableEntry Entry{get;private set;}

        public PriorityQueueEntry(TPriorityValue val,IIdentifiableEntry entry)
        {
            Priority = val;
            Entry = entry;
        }
        public int Compare(PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType> first, PriorityQueueEntry<TPriorityValue,IIdentifiableEntry,IType> second) 
        {
            if (first.Priority.CompareTo(second.Priority) < 0)
            {
                return -1;
            }
            else if (first.Priority.CompareTo(second.Priority) > 0)
            {
                return 1;
            }
            return first.Entry.Id.ToUInt32(NumberFormatInfo.CurrentInfo) < first.Entry.Id.ToUInt32(NumberFormatInfo.CurrentInfo) ? -1:1; 
        }
    }
于 2012-11-13T13:18:49.000 に答える