C#泛型类和EqualityComparer

时间:2012-11-13 12:44:55

标签: c# generics static icomparable icomparer

任何人都可以在下面的类声明中解释我的错误:

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)'不能   使用实例引用访问,使用类型名称限定它   代替

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


对不起,我的错。我发布了一个不完整的问题 为了完整起见,Idetifier类就是以下内容:

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

在那里使用EqualityComparer,是由于复制和粘贴错误(对不起家伙,今天太多的通用代码)。

当然我的问题被误解了,因为我没有给你所需要回答的所有元素(我很快就会把它删除)。 我需要ITypeIConvertible。 无论如何,感谢所有人。

3 个答案:

答案 0 :(得分:6)

这是一个实例引用:

EqualityComparer<IIdentifiableEntry>.Default

第一个问题是你根本不打电话给object.Equals(object, object)。你真的想在相等比较器上调用方法 - 但是你试图用不能转换为IIdentifieableEntry的参数来调用它。

第二个问题是您尝试执行排序比较,而不是相等比较,因此您需要Comparer<T>,而不是{{1 }}

目前尚不清楚您要实现的目标,但此代码至少编译

EqualityComparer<T>

如果你真的想要比较Id属性,你需要一个ID属性类型的相等比较器 - 我们不知道那个类型是什么。

我怀疑你真的想要这样的东西

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

...但这取决于return Comparer<string>.Default.Compare(first.Entry.Id, second.Entry.Id); 的类型。

答案 1 :(得分:3)

您尚未显示Identifier声明或EqualityComparer声明。但我认为您需要将行更改为:

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

<强> [编辑]

根据Jon的评论。你根本不想要平等比较器。 Asumming表示Entry.Id是IComparable,然后只是:

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

我建议Entry只限于IComparable,所以我们得到类似的内容:

class PriorityQueueEntry&gt;             其中TPriorityValue:IComparable             其中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是一个类,你可能想要添加一些空检查。

答案 2 :(得分: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; 
        }
    }