【问题标题】:Generics and Implementing IComparable泛型和实现 IComparable
【发布时间】:2012-02-01 10:26:05
【问题描述】:

我对泛型非常陌生,我正在尝试编写一个简单的类,它是泛型的,但也允许对字符串成员变量的一些描述进行排序。

目前我有一个基本类,但是当我尝试实现接口成员 CompareTo() 时,我在顶部收到一个错误,告诉我它没有实现。这里有什么问题?

using System;

namespace GenericsPracticeConsole.Types
{
    class SortableGenericType<T> : IComparable
    {
        private T t;
        private string stringName;

        public T name
        {
            get { return t; }
            set { t = value; }
        }

        public int CompareTo(SortableGenericType<T> ourObject)
        {
            return stringName.CompareTo(ourObject.stringName);
        }
    }
}

【问题讨论】:

    标签: c# .net generics icomparable


    【解决方案1】:

    IComparableIComparable&lt;U&gt;两个接口。 IComparable 是较旧的(在泛型之前出现),它需要将实例与任意对象进行比较。 IComparable&lt;U&gt; 要求将实例与U 的实例进行比较。如果您想声明您将在 stringName 字段上比较 SortableGenericType 的实例,您应该这样做:

    class SortableGenericType<T> : IComparable<SortableGenericType<T>>
    {
       //
    }
    

    如果你也想实现 IComparable:

       class SortableGenericType<T> : IComparable, IComparable<SortableGenericType<T>> 
       {
          private string stringName;
          public T name { get; set; }
    
          public int CompareTo(SortableGenericType<T> ourObject)
          {
             //I forgot to add this statement:
             if(ourObject == null) 
                 return -1; 
             return stringName.CompareTo(ourObject.stringName);
          }
    
          public int CompareTo(object obj)
          {
             if (obj.GetType() != GetType())
                return -1;
             return CompareTo(obj as SortableGenericType<T>);
          }
       }
    

    如果你的类是一个集合,它将包含 T 类型的项目,并且你需要这些项目是可订购的(这不是你要求的,但这是最常见的情况),那么你需要 T成为IComparable&lt;T&gt;

       class SomeCollection<T> where T : IComparable<T>
       {
          private List<T> items; 
    
          private void Sort()
          {
             //
             T item1;
             T item2;
             if(item1.CompareTo(item2) < 0)
             {
                //bla bla
             }
          }
       }
    

    【讨论】:

    • 我不会做if (obj.GetType() != GetType()) return -1;,因为那样你的比较就不再是反对称或自反了。
    • 是的。但我不知道在这种情况下我应该做什么。你的建议是什么?
    • 在第二个 CompareTo 函数中,您使用这一行: return CompareTo(obj as SortableGenericType);这一行是否隐含地比较了我们拥有的当前对象和传递的对象,而没有实际引用该行中的当前项目?
    • 好的。所以我最初的问题是: return CompareTo(obj as SortableGenericType);此行是否基本上将调用它的当前对象与传递的对象(即 myInstance.CompareTo(passedInstance) 仅在没有实际指定 this.CompareTo 或类似的情况下进行比较?很抱歉再次问,但我想明确一点,在继续之前我知道发生了什么。感谢您的帮助。
    • @CSharpened:如果有人实现子类 SubSortableGType 并将 SubSortableGType 类型的参数传递给 CompareTo,那么您的建议就会中断。但这提醒我,我忘记了 ourObject 可能为空的情况,我为这种情况添加了一行。谢谢。 obj as SortableGenericType&lt;T&gt;obj 强制转换为SortableGenericType&lt;T&gt;,如果不成功则结果为null,因此如果您传递不相关类型的参数,CompareTo 将使用null 调用,结果将始终为“小于”。在不了解用例的情况下很难提出更好的建议。
    【解决方案2】:

    IComparable 定义了方法public int CompareTo(object obj)。请注意参数类型 - 它是 object,而不是您自己的类型。这就是您实际上没有实现接口的原因。

    你需要做的是实现IComparable&lt;SortableGenericType&lt;T&gt;&gt;

    【讨论】:

    • 完美。非常感谢。我认为由于我的类型本身就是一个对象,因此可以这样做。感谢您的解释。
    • 你的类型是一个对象,但它是一个特定的对象。 IComparable 允许您将您的对象与任何对象进行比较,而不仅仅是您的特定类型。
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多