作者:l625208058

链接:https://www.jianshu.com/p/cd1be6652570


先 F12 看下 List.Sort() 方法

public void Sort(int index, int count, IComparer<T> comparer);  //指定范围排序
public void Sort(Comparison<T> comparison); //Comparison<T>其实就是个委托
public void Sort(); //使用默认排序
public void Sort(IComparer<T> comparer); //使用一个自定义排序者

一. Comparison<T>

public delegate int Comparison<in T>(T x, T y);

这其实就是个委托,排序示例:

 Dictionary<string, int> dic = new Dictionary<string, int>();
dic.Add("index.html", 50);
dic.Add("product.html", 13);
dic.Add("aboutus.html", 4);
dic.Add("online.aspx", 22);
dic.Add("news.aspx", 18); public static int h1(KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
{
return s2.Value.CompareTo(s1.Value);
} //第一种,使用预先定义的静态方法
List<KeyValuePair<string, int>> list1 = new List<KeyValuePair<string, int>>(dic);
list1.Sort(h1); //第二种,使用Dictionary<string, int> dic = new Dictionary<string, int>();
dic.Add("index.html", 50);
dic.Add("product.html", 13);
dic.Add("aboutus.html", 4);
dic.Add("online.aspx", 22);
dic.Add("news.aspx", 18); public static int h1(KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
{
return s2.Value.CompareTo(s1.Value);
} //第一种,使用预先定义的静态方法
List<KeyValuePair<string, int>> list1 = new List<KeyValuePair<string, int>>(dic);
list1.Sort(h1); //第二种,使用匿名方法
List<KeyValuePair<string, int>> list2 = new List<KeyValuePair<string, int>>(dic);
list1.Sort(delegate (KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
{
return s2.Value.CompareTo(s1.Value);
}); //第三种,使用 lambda 表达式
List<KeyValuePair<string, int>> list3 = new List<KeyValuePair<string, int>>(dic);
list2.Sort((s1, s2) => { return s1.Value.CompareTo(s2.Value); });

二. Comparer<T>IComparer<T>

1. 概念:为 IComparer<T>泛型接口实现提供的基类。

public abstract class Comparer<T> : IComparer, IComparer<T>
{
protected Comparer();
public static Comparer<T> Default { get; }
public static Comparer<T> Create(Comparison<T> comparison);
public abstract int Compare(T x, T y);
}

2. Comparer<T>IComparer<T>的区别:

  • Comparer是类,并提供了默认比较器,也就是说,如果需要自定义默认比较器,需要自行实现IComparer接口

  • 使用Comparer.Default来获取默认比较器

  • IComparer 就是提供一个统一的比较接口,而Comparer就是官方为你提供的一个抽象实现类,具体还是得要你重写实现

三. IComparable<T>

自己设计的模型类需要比较,可继承此接口,实现后就可以直接使用排序

接口类:

public interface IComparable<in T>
{
int CompareTo(T other);
}

四. Comparer<T>IComparer<T>IComparable<T>官方案例

class Test
{
static void Main(string[] args)
{
List<Box> Boxes = new List<Box>();
Boxes.Add(new Box(4, 20, 14));
Boxes.Add(new Box(12, 12, 12));
Boxes.Add(new Box(8, 20, 10));
Boxes.Add(new Box(6, 10, 2));
Boxes.Add(new Box(2, 8, 4));
Boxes.Add(new Box(2, 6, 8));
Boxes.Add(new Box(4, 12, 20));
Boxes.Add(new Box(18, 10, 4));
Boxes.Add(new Box(24, 4, 18));
Boxes.Add(new Box(10, 4, 16));
Boxes.Add(new Box(10, 2, 10));
Boxes.Add(new Box(6, 18, 2));
Boxes.Add(new Box(8, 12, 4));
Boxes.Add(new Box(12, 10, 8));
Boxes.Add(new Box(14, 6, 6));
Boxes.Add(new Box(16, 6, 16));
Boxes.Add(new Box(2, 8, 12));
Boxes.Add(new Box(4, 24, 8));
Boxes.Add(new Box(8, 6, 20));
Boxes.Add(new Box(18, 18, 12)); //使用继承了Comparer<T>的比较器,进行排序。里面覆写了Compare(T a,T b)方法
Boxes.Sort(new BoxLengthFirst()); foreach (Box bx in Boxes)
{
Console.WriteLine("{0}\t{1}\t{2}",
bx.Height.ToString(), bx.Length.ToString(),
bx.Width.ToString());
} Console.WriteLine("==============="); //获取默认比较器
Comparer<Box> defComp = Comparer<Box>.Default; // 等于调用Boxs.Sort(defComp);
Boxes.Sort(); foreach (Box bx in Boxes)
{
//输出高、长、宽
Console.WriteLine("{0}\t{1}\t{2}",
bx.Height.ToString(), bx.Length.ToString(),
bx.Width.ToString());
} BoxLengthFirst LengthFirst = new BoxLengthFirst(); Comparer<Box> bc = (Comparer<Box>)LengthFirst; Box BoxA = new Box(2, 6, 8);
Box BoxB = new Box(10, 12, 14);
int x = LengthFirst.Compare(BoxA, BoxB);
Console.WriteLine();
Console.WriteLine(x.ToString()); Console.ReadLine();
}
} public class BoxLengthFirst : Comparer<Box>
{
//父类抽象方法 Compare
public override int Compare(Box x, Box y)
{
if (x.Length.CompareTo(y.Length) != 0)
{
return x.Length.CompareTo(y.Length);
}
else if (x.Height.CompareTo(y.Height) != 0)
{
return x.Height.CompareTo(y.Height);
}
else if (x.Width.CompareTo(y.Width) != 0)
{
return x.Width.CompareTo(y.Width);
}
else
{
return 0;
}
} } //没有在Main方法里演示,推荐使用继承Comparer<T>的方法。
public class BoxComp : IComparer<Box>
{
// Compares by Height, Length, and Width.
public int Compare(Box x, Box y)
{
if (x.Height.CompareTo(y.Height) != 0)
{
return x.Height.CompareTo(y.Height);
}
else if (x.Length.CompareTo(y.Length) != 0)
{
return x.Length.CompareTo(y.Length);
}
else if (x.Width.CompareTo(y.Width) != 0)
{
return x.Width.CompareTo(y.Width);
}
else
{
return 0;
}
}
} public class Box : IComparable<Box>
{
public Box(int h, int l, int w)
{
this.Height = h;
this.Length = l;
this.Width = w;
}
public int Height { get; private set; }
public int Length { get; private set; }
public int Width { get; private set; } public int CompareTo(Box other)
{
if (this.Height.CompareTo(other.Height) != 0)
{
return this.Height.CompareTo(other.Height);
}
else if (this.Length.CompareTo(other.Length) != 0)
{
return this.Length.CompareTo(other.Length);
}
else if (this.Width.CompareTo(other.Width) != 0)
{
return this.Width.CompareTo(other.Width);
}
else
{
return 0;
}
}
}

五. Comparison<T>Comparer<T>System.IComparableIComparable<T>的区别

  1. Comparison<T>,继承委托。开发人员可以在外部写个用于比较大小的函数,然后作为Comparison<T>类型的参数传入,进行比较,非常方便。

  2. 派生自 Comparer<T> 类和实现 System.IComparable 接口之间的差异如下:

    • 若要指定默认情况下(Default获取)应如何比较两个对象,请在类中实现System.IComparable 接口。 这可确保排序操作将使用您提供的默认比较代码。

    • 若要定义要使用的比较器而不是默认比较器,请从 Comparer<T> 类派生。 然后,您可以在采用比较器作为参数的排序操作中使用此比较器。

  3. Default 属性返回的对象使用 System.IComparable<T> 泛型接口来比较两个对象。 如果类型 T 未实现 System.IComparable<T> 泛型接口,Default 属性返回使用System.IComparable 接口的 Comparer<T>

C#比较类/接口、Dictionary 排序的更多相关文章

  1. Entity Framework 实体框架的形成之旅--为基础类库接口增加单元测试,对基类接口进行正确性校验(10)

    本篇介绍Entity Framework 实体框架的文章已经到了第十篇了,对实体框架的各个分层以及基类的封装管理,已经臻于完善,为了方便对基类接口的正确性校验,以及方便对以后完善或扩展接口进行回归测试 ...

  2. Entity Framework 实体框架的形成之旅--基类接口的统一和异步操作的实现(3)

    在本系列的第一篇随笔<Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)>中介绍了Entity Framework 实体框架的一些基础知识,以及构建 ...

  3. C#中Dictionary排序方式

    转载自:https://www.cnblogs.com/5696-an/p/5625142.html 自定义类: https://files.cnblogs.com/files/xunhanliu/d ...

  4. Java类/接口的API

    本章节收集的类/接口API有: Object类,枚举,包装类,接口Comparable,类Arrays,异常, Object类 public String toString(): [把一个对象的信息用 ...

  5. Java基础 TreeSet()来实现数组的【定制排序】 : Comparable接口(自然排序) 或者 Comparator接口 (定制排序)

    笔记: //排序真麻烦!没有C++里的好用又方便!ORZ!ORZ!数组排序还还自己写个TreeSet()和( Comparable接口(自然排序) 或者 Comparator接口 (定制排序))imp ...

  6. C#语法基础用法Dictionary排序

    Dictionary排序 1.先看效果图: 2.核心逻辑如下: Dictionary<int, string> list = new Dictionary<int, string&g ...

  7. C#实现Comparable接口实现排序

    C#中,实现排序的方法有两种,即实现Comparable或Comparer接口,下面简单介绍实现Comparable接口实现排序功能. 实现Comparable接口需要实现CompareTo(obje ...

  8. C#字典Dictionary排序(顺序、倒序)

    这里是针对.NET版本过低的排序方式,没怎么用过,记录一下: 一.创建字典Dictionary 对象 假如 Dictionary 中保存的是一个网站页面流量,key 是网页名称,值value对应的是网 ...

  9. 存储数据键和项目对的类(Dictionary对象)

    存储数据键和项目对的类(Dictionary对象) <% Class Dictionary Public Copyright, Developer, Name, Version, Web Pri ...

  10. 业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份

    业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份 WinForm酒店管理软件--框架这篇随笔可以说是我写的最被大家争议的随笔,一度是支持和反对是一样的多.大家对我做的这个行业 ...

随机推荐

  1. C#读取XML字符串及将XML字符串反序列化为对象

    在开发中遇到调用接口范围XML格式结果情况,获取结果中我们需要的信息则可能需要这两种数据处理: 1.如何将xml字符串转换为xml对象,及查询想要的节点: 通过XmlDocument对象加载xml字符 ...

  2. 2022-3-16内部群每日三题-清辉PMP

    1.项目经理正在为客户管理一个跨国项目,拟采用最新技术替换其电信基础设备.项目经理得知,在某些国家,必须遵循特定的环境规定来处置被替换的硬件.在制定商业论证时,未考虑到这些规定,项目经理应该怎么做? ...

  3. google api 后端打点上报

    https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type ...

  4. mysql-列拆分

    tableA id warehouse_id 1 1,2 想要的结果: id warehouse_id 1 1 2 2 select *(其他的字段), substring_index(substri ...

  5. vantUI <van-uploader> 上传图片,如何获取图片的尺寸

    html代码 <van-uploader preview-size="300px" style="width:300px;display:block;margin: ...

  6. Day14-封装、继承、多态

    封装.继承.多态 一.封装 package Demo; //类 private私有 public class student { //属性私有 //名字 private String name; // ...

  7. Java基础|02.方法的传递机制

    Java基础|02.方法传参机制 0x00 前言 Parameter:参数 java中只有传值,因为地址值也是值 0x01 基础数据类型的传参机制 基本数据类型的值传递,不改变原值.因为调用后会弹栈, ...

  8. Spring系列之基于环境抽象-10

    目录 Bean 定义配置文件 使用 `@Profile` XML Bean 定义配置文件 激活配置文件 默认配置文件 `PropertySource` 使用`@PropertySource` Envi ...

  9. spring-security-oauth2使用遇到的坑

    异常信息为 2021-08-22 14:24:11.086 WARN 17812 --- [ main] ConfigServletWebServerApplicationContext : Exce ...

  10. 面向对象ooDay9

    精华笔记: 多态:多种形态 同一个对象被造型为不同的类型时,有不同的功能-------所有对象都是多态的(明天总结详细讲) 对象的多态:水.我.你...... 同一类型的引用在指向不同的对象时,有不同 ...