代码之家  ›  专栏  ›  技术社区  ›  Razor

比较器是用来干什么的?

c#
  •  24
  • Razor  · 技术社区  · 14 年前

    这个计划的目的是什么 Comparer<T> 如果指定的类型已实现 IComparable ?

    7 回复  |  直到 13 年前
        1
  •  19
  •   Josh    14 年前

    Comparer<T> IComparer<T> 除了基类为您提供了一个泛型和非泛型实现以及一个重写的方法之外。

    但如果你的问题是为什么两者都有呢 IComparable<T> 正如其他人所指出的, 比较器<T> 允许您定义执行比较的不同方法。它是 Strategy design pattern StringComparer 属性,如StringComparer.Ordinal、StringComparer.OrdinalIgnoreCase等。这允许您在 i可比较<T> 接口根本无法预料。

    因此,归根结底,这只是另一个扩展点,当您不是要排序的类型的作者(或者您需要多种排序策略)时,它允许您具有更大的灵活性


    编辑:针对您的以下评论: 如果我有一个实现IComparer的类(我自己的类),这将允许我对任意数量的属性进行排序(自定义排序),那么我为什么要费心使用Comparer.Default呢

    也许举个例子会有帮助。假设您正在编写一个扩展方法来检查给定值是否在一个范围之间。

    public static bool Between<T>(this T value, T minValue, T maxValue) {
    
        var comparer = Comparer<T>.Default;
    
        int c1 = comparer.Compare(value, minValue);
        int c2 = comparer.Compare(value, maxValue);
    
        return (c1 >= 0 && c2 <= 0);
    
    }
    

    IComparable 或者它可以实现

        2
  •  22
  •   Maja Piechotka    14 年前

    例如,如果有平面线,则可能需要按以下方式对其排序:

    • 航班号
    • 目的地
    • 时间
    • ...

    计算机中的任务可以通过以下方式安排:

    • 用户
    • PID(正常比较)
    • ...

    因此,即使在一个应用程序中,也可能需要按不同的属性对对象进行排序。你不能靠 int compareTo(Object) 方法,因为它不能区分上下文。但是,您可以添加上下文,即实现 CompareByPriority

        3
  •  9
  •   Kobi    14 年前

    类型不需要实现IComparable,它可以是任何类型- 没有限制 T :

    public abstract class Comparer<T> : IComparer, IComparer<T>
    

    新的 Comparer IComparer<T> 非通用的 IComparer ,并可用于集合的比较和排序。

    你是对的:如果你喜欢的类型, Customer 工具 IComparable ,你不需要再比较, IComparable<T> Comparer<T> ,所以您可以使用其中任何一个。

    比较器

    public abstract class Comparer<T> : IComparer, IComparer<T>
                                        where T : IComparable, IComparable<T>
    

    Person 你想给一个 Persons

    public class Person
    {
        string Name { get; set; }
    }
    
        4
  •  8
  •   Marc Gravell    14 年前

    这里有几个微妙之处:

    • IComparable<T> -它还支持较旧的(非通用) IComparable 作为退路。这意味着 表示为(例如)泛型约束
    • 它支持 Nullable<T> 哪里 T 可为空<T> 清晰地 不是吗 I可比较
    • 它通过以下方式防止泛型类型约束的爆炸 要求他们-例如 List<T> Sort 即使没有 坚持 T 是可排序的;你会的 否则泛型约束累积的速度有多快
    • 它能让你通过考试 比较器 当您只有一个 类型 具有可比性;大多数框架排序API(包括LINQ)将提供比较器支持
        5
  •  2
  •   Seattle Leonard    14 年前
    public class Person
    {
        public string LastName;
        public string FirstName;
    
    }
    
    public class Class2
    {
        public void test()
        {
            List<Person> classList = new List<Person>();
            //add some data to the list
            PersonComparer comp = new PersonComparer();
            classList.Sort(comp);
        }
    }
    
    public class PersonComparer : Comparer<Person>
    {
    
        public override int Compare(Person x, Person y)
        {
            int val = x.LastName.CompareTo(y.LastName);
            if (val == 0)
            {
                val = x.FirstName.CompareTo(y.FirstName);
            }
            return val;
        }
    }
    
        6
  •  1
  •   nawfal Donny V.    11 年前

    IComparable<T> ,几乎可以肯定,使用它比 IComparable . 对于值类型 通常要比非泛型的好得多 I可比较 i可比较<T> 可以提供比 允许基于派生类型字段进行排名。

    对于后一个好处的例子,假设有一个抽象的基类 ScheduleEvent EventTime ,实现 IComparable<ScheduleEvent> 按排序 ScheduledPopupMessageEvent 使用消息字符串 ScheduledGongEvent GongVolume 他和我一样 事件时间 IComparable<ScheduleEvent>.CompareTo ,因为没有安全一致的排名方式 不同类型的,因为 为保持一致性,两个都报告自己相对于第三个未分级的对象必须报告自己相对于另一个未分级的对象。另一方面,拥有 ScheduledGongEvent事件 IComparable<ScheduledGongEvent> 贡品卷 考虑到 ,或与 计划PopupMessageEvent 对其消息参数执行同样的操作。

    i可比较<T> 如果它存在,但能够回落到 I可比较 如果 不存在。检查类是否实现 i可比较<T> 执行,它可以依赖于始终有一个;同样,如果发现一个类型没有这样的实现,它永远不会有。此外,如果泛型类具有任何静态字段,则类型参数的每个组合都将产生具有不同字段的不同类。因此,第一次 Comparer<T>.Default 如果使用特定的类型参数T运行,它将把返回的比较器例程存储到静态字段中。如果 Comparer<T> 再次使用相同类型运行时,它将返回相同的比较器例程。尽管有一个静态的 只使用一个方法初始化,创建一个单独的 比较器<T> 每种类型的类 T 提供存储创建的比较例程的位置。

        7
  •  0
  •   brickner    14 年前

    Comparer<T> 保存实际的比较方法。如果您想以不同于您的方式比较对象,可以使用它 IComparable