比较和排序 IComparable And IComparer

1.List<Student>默认排序

为类创建默认排序实现IComparable,此代码的实现为年龄升序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IComparable_And_IComparer.Model
{
    /// <summary>
    /// 学生类
    /// </summary>
    /*
     如果需要对类进行排序,那么我们需要实现IComparable接口中的CompareTo比较方法
     */
    public class Student : IComparable<Student>
    {
        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 学号
        /// </summary>
        public string No { get; set; }



        /*
        需要注意的是此比较方法为
        :本身对象与另一对象做比较
            如果返回为大于等于1:则认为本身对象(this)应排列在后
            如果返回为小于等于-1:则认为本身对象应排列在前(0开始为前)
            如果返回为等于0:则认为此对象本身比较对象位置不变
        所以可以根据此方式去实现升序和降序
          
        如果只是使用,只要记住 this.xxx.CompareTo(other.xxx)为升序;other.xxx.CompareTo(this.xxx)为降序 
         
        以下内容(可无视)
        
        均为钻牛角尖思考: 
        理解说明:由于所有元素都会进行比较,都会以this进行比较,
         * (升序)所以如果需要大的排在后面 我们只需要CompareTo返回时规定如果本身大于比较的值(也就是说如果我们选择 本身减去比较 那么表示我们需要本身大于比较的值排在后面){ 因为如果本身是大于的话,那么值就会排到后面,小于的话值就会到前面去}
         * (降序)所以如果需要大的排在后面 我们只需要CompareTo返回时规定如果本身小于比较的值
         * 
         * 
         * 
         
         初略辅助理解:因为最终所有元素都会进行比较(也就是所有元素都会成为this)
         * 如果是this.Age.CompareTo(other.Age);    
         *  因为
         *      如果本身大于比较的值,那么则会到后面去
         *      小于则排到前面去
         *  而因为认为所有元素都会成为this所以所有元素大的都会到后面去
        */
        /// <summary>
        /// 实现排序
        /// </summary>
        /// <param name="other">比较的对象</param>
        /// <returns>
        /// 等于0:相等  (表示与做比较的对象相等);
        /// 大于等于1:大于(表示大于比较的对象);
        /// 小于等于-1:小于(表示小于比较的对象);
        /// </returns>
        public int CompareTo(Student other)
        {
            //if (this.Age > other.Age)
            //    return 1;
            //else if (this.Age == other.Age)
            //    return 0;
            //else
            //    return -1;

            //return this.Age - other.Age;       //本身大于比较的对象,排于后面
            return this.Age.CompareTo(other.Age);//希望大于的排在后面(升序)    
            //return this.Age.CompareTo(other.Age);//希望小于的排在后面(降序)
        }
    }
}

使用:

List<Student> list= new List<Student>()
                {
                    new Student() { Age = 2, Name = "B", No = "A002" },
                    new Student() { Age = 1, Name = "A1", No = "A001" },
                    new Student() { Age = 3, Name = "A2", No = "A0010" },
                    new Student() { Age = 5, Name = "A3", No = "A0015" },
                    new Student() { Age = 6, Name = "A4", No = "A0016" },
                    new Student() { Age = 10, Name = "A5", No = "A0011" },
                    new Student() { Age = 11, Name = "A9", No = "A0012" },
                    new Student() { Age = 12, Name = "A11", No = "A0013" },
                    new Student() { Age = 31, Name = "A12", No = "A0014" },
                 };

list.Sort();

2.List<Student> 使用自定义排序比较器实现多种排序方式(需要多少种排序方式就需要定义多少个类去实现接口):实现IComparer接口

using IComparable_And_IComparer.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IComparable_And_IComparer.SortComparer
{
    /// <summary>
    /// 有泛型的接口,应该明确表明类型,否则为object
    ///     会造成拆箱与装箱问题
    /// </summary>
    public class NameASC : IComparer<Student>
    {
        /// <summary>
        /// 相关注释描述参考Student类,Student类中this为此方法中x
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public int Compare(Student x, Student y)
        {
            return x.Name.CompareTo(y.Name);
        }
    }
}

使用:

list.Sort(new NameASC());

3.linq动态排序

       if (true)
                list = (from p in list
                        //orderby 后面需要接上值,来让其为每条数据作比较
                        orderby GetPropertyValue(p, txtFieldOrder.Text) ascending
                        select p).ToList();
            else
                list = (from p in list
                        //orderby 后面需要接上值,来让其为每条数据作比较
                        orderby GetPropertyValue(p, txtFieldOrder.Text) descending
                        select p).ToList();


     /// <summary>
        /// 获取一个对象的属性值
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="property">属性名</param>
        /// <returns></returns>
        private static object GetPropertyValue(object obj, string property)
        {
            System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(property);
            return propertyInfo.GetValue(obj, null);
        }
原文地址:https://www.cnblogs.com/ChenRihe/p/4566959.html