【问题标题】:C# generic class and EqualityComparerC# 泛型类和 EqualityComparer
【发布时间】:2012-11-13 12:44:54
【问题描述】:

谁能解释一下下面的类声明有什么问题:

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,是由于复制和粘贴错误(抱歉,今天的通用代码太多)。

当然我的问题是错误的,因为我没有给你所有你需要回答的元素(我很快就会删除它)。 我需要IType 成为IConvertible。 总之谢谢大家。

【问题讨论】:

    标签: c# generics static icomparable icomparer


    【解决方案1】:

    这是一个实例引用:

    EqualityComparer<IIdentifiableEntry>.Default
    

    第一个问题是您根本不想想要致电object.Equals(object, object)。您确实想在相等比较器上调用该方法 - 但您尝试使用不可转换为 IIdentifieableEntry 的参数调用它。

    第二个问题是您正在尝试执行 ordering 比较,而不是 equality 比较,因此您需要Comparer&lt;T&gt;,而不是EqualityComparer&lt;T&gt;

    不清楚您要实现什么,但这段代码至少可以编译

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

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

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

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

    ...但这取决于Id的类型。

    【讨论】:

    • 这段代码不会编译,因为 Equals 返回一个 bool 并且该方法应该返回一个 int
    • 实际上 IType : IConvertible 解决了我的问题。抱歉,问题不完整。
    【解决方案2】:

    您没有显示 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> 其中 TPriorityValue : IComparable 其中 TENtry : IComparable { 公共 TPriorityValue 优先级{get;私有集;} 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 是一个类,您可能需要添加一些空检查。

    【讨论】:

    • Equals 不是EqualityComarer&lt;T&gt; 中的模板化方法
    • 我的错。我用谷歌搜索它,它只返回 IEqualityComparer。嗯。请忽略之前的回答。我将编辑一个新答案。
    【解决方案3】:

    最后我这样解决了:

    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; 
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多