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)',而是使用类型名称对其进行限定

我看不到我在哪里使用实例引用。


对不起,我的错。我发布了一个不完整的问题。为了完整起见,标识符类如下:

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.

第二个问题是您正在尝试执行排序比较,而不是相等比较,所以您想要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,因此我们会得到如下信息:

类 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 是一个类,您可能需要添加一些空检查。

于 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 回答