在最近一个项目中,有需求要对页面中所有的gridview添加排序功能。由于gridview的数据源绑定的是一个集合类List,而不是DataTable,所以无法使用DataView排序功能。另外,不同的gridview显示的是不同的业务数据,为了重用代码只能添加一个泛型方法,使用该方法对数据类型T,按照任意给定的属性进行排序。由于是要按照某个不固定的属性对List内的对象进行排序,所以修改类型T,使之实现IComparable接口,并利用List类的Sort () 方法进行排序是无法满足需求的。但是List类还提供了另一个Sort方法,它接受一个IComparer对象作为参数,在IComparer内可以实现排序的业务逻辑。唯一需要的就是进行排序的属性了,而这个在程序的上下文是已知的。

  思路已经有了,但动手写代码前,google了一下相关文章,竟然发现有一段功能类似的代码,唯一不同是该该代码的实现中方法并不是泛型的。但是强大的地方是,代码中对实现的排序支持按照多个属性排序。于是稍加修改,一段强大的支持按照多属性对List进行排序的泛型方法就出炉了。

  首先是表示排序属性和排序方向的类SortClass,其中保存了排序的属性和排序的方向。

  1. /// <summary>
  2. /// Class used to hold sort information
  3. /// </summary>
  4. public class SortClass
  5. {
  6. private string _sortProperty;
  7.  
  8. public string SortProperty
  9. {
  10. get { return _sortProperty; }
  11. set { _sortProperty = value; }
  12. }
  13. private SortDirection _sortDirection;
  14.  
  15. public SortDirection SortDirection
  16. {
  17. get { return _sortDirection; }
  18. set { _sortDirection = value; }
  19. }
  20.  
  21. public SortClass(string sortProperty, SortDirection sortDirection)
  22. {
  23. _sortProperty = sortProperty;
  24. _sortDirection = sortDirection;
  25. }

Normal
0

false
false
false

MicrosoftInternetExplorer4

/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}

  有了SortClass后就可以开始实现IComparar接口了。下面是Comparer的代码,它实现了IComparar接口,包含实际的排序功能。从代码中可以看出,Comparer通过递归调用CheckSort方法来首先按照多个属性排序的。

  1. /// <summary>
  2. /// Implementation of IComparer
  3. /// </summary>
  4. public class Comparer<T> : IComparer<T>
  5. {
  6. private List<SortClass> _sortClasses;
  7.  
  8. /// <summary>
  9. /// Collection of sorting criteria
  10. /// </summary>
  11. public List<SortClass> SortClasses
  12. {
  13. get { return _sortClasses; }
  14. }
  15.  
  16. /// <summary>
  17. /// Default Constructor
  18. /// </summary>
  19. public Comparer()
  20. {
  21. _sortClasses = new List<SortClass>();
  22. }
  23.  
  24. /// <summary>
  25. /// Constructor that takes a sorting class collection as param
  26. /// </summary>
  27. /// <param name="sortClass">
  28. /// Collection of sorting criteria
  29. ///</param>
  30. public Comparer(List<SortClass> sortClass)
  31. {
  32. _sortClasses = sortClass;
  33. }
  34.  
  35. /// <summary>
  36. /// Constructor
  37. /// </summary>
  38. /// <param name="sortProperty">Property to sort on</param>
  39. /// <param name="sortDirection">Direction to sort</param>
  40. public Comparer(string sortProperty, SortDirection sortDirection)
  41. {
  42. _sortClasses = new List<SortClass>();
  43. _sortClasses.Add(new SortClass(sortProperty, sortDirection));
  44. }
  45.  
  46. /// <summary>
  47. /// Implementation of IComparer interface to compare to object
  48. /// </summary>
  49. /// <param name="x"></param>
  50. /// <param name="y"></param>
  51. /// <returns></returns>
  52. public int Compare(T x, T y)
  53. {
  54. if (SortClasses.Count == )
  55. {
  56. return ;
  57. }
  58. return CheckSort(, x, y);
  59. }
  60.  
  61. /// <summary>
  62. /// Recursive function to do sorting
  63. /// </summary>
  64. /// <param name="sortLevel">Current level sorting at</param>
  65. /// <param name="myObject1"></param>
  66. /// <param name="myObject2"></param>
  67. /// <returns></returns>
  68. private int CheckSort(int sortLevel, T myObject1, T myObject2)
  69. {
  70. int returnVal = ;
  71. if (SortClasses.Count - >= sortLevel)
  72. {
  73. object valueOf1 = myObject1.GetType().GetProperty(SortClasses[sortLevel].SortProperty).GetValue(myObject1, null);
  74. object valueOf2 = myObject2.GetType().GetProperty(SortClasses[sortLevel].SortProperty).GetValue(myObject2, null);
  75. if (SortClasses[sortLevel].SortDirection == SortDirection.Ascending)
  76. {
  77. returnVal = ((IComparable)valueOf1).CompareTo((IComparable)valueOf2);
  78. }
  79. else
  80. {
  81. returnVal = ((IComparable)valueOf2).CompareTo((IComparable)valueOf1);
  82. }
  83.  
  84. if (returnVal == )
  85. {
  86. returnVal = CheckSort(sortLevel + , myObject1, myObject2);
  87. }
  88. }
  89.  
  90. return returnVal;
  91. }
  92. }

Normal
0

false
false
false

MicrosoftInternetExplorer4

/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}

  准备工作完成后,就可以开始实现真正强大的泛型排序方法了。ListSorter提供了2个静态方法,一个用来对多个属性排序,另一个为了方便只针对一个属性进行排序的情况。

  1. public class ListSorter
  2. {
  3. public static List<T> SortList<T>(List<T> listToSort, List<string> sortExpression, List<SortDirection> sortDirection)
  4. {
  5. //check parameters
  6. if (sortExpression.Count != sortDirection.Count||sortExpression.Count==||sortDirection.Count==)
  7. {
  8. throw new Exception("Invalid sort arguments!");
  9. }
  10.  
  11. //get myComparer
  12. Comparer<T> myComparer = new Comparer<T>();
  13. for (int i = ; i < sortExpression.Count; i++)
  14. {
  15. SortClass sortClass = new SortClass(sortExpression[i], sortDirection[i]);
  16. myComparer.SortClasses.Add(sortClass);
  17. }
  18. listToSort.Sort(myComparer);
  19. return listToSort;
  20. }
  21.  
  22. public static List<T> SortList<T>(List<T> listToSort, string sortExpression, SortDirection sortDirection)
  23. {
  24. //check parameters
  25. if (sortExpression == null || sortExpression == string.Empty || sortDirection == null)
  26. {
  27. return listToSort;
  28. }
  29.  
  30. Comparer<T> myComparer = new Comparer<T>();
  31. myComparer.SortClasses.Add(new SortClass(sortExpression, sortDirection));
  32. listToSort.Sort(myComparer);
  33. return listToSort;
  34. }
  35. }

Normal
0

false
false
false

MicrosoftInternetExplorer4

/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}

有了上面的代码,只需简单几行就可以轻松实现对泛型List的排序功能了:

  1. List<Project> projectList=...;
  2. List<Project> sortedProject = ListSorter.SortList(projectList, "Name", SortDirection.Ascending);

出处:http://www.cnblogs.com/dytes/archive/2009/01/06/1370623.html

泛型List<T>排序(利用反射)的更多相关文章

  1. DataTable转任意类型对象List数组-----工具通用类(利用反射和泛型)

    public class ConvertHelper<T> where T : new() { /// <summary> /// 利用反射和泛型 /// </summa ...

  2. 利用反射快速给Model实体赋值 使用 Task 简化异步编程 Guid ToString 格式知多少?(GUID 格式) Parallel Programming-实现并行操作的流水线(生产者、消费者) c# 无损高质量压缩图片代码 8种主要排序算法的C#实现 (一) 8种主要排序算法的C#实现 (二)

    试想这样一个业务需求:有一张合同表,由于合同涉及内容比较多所以此表比较庞大,大概有120多个字段.现在合同每一次变更时都需要对合同原始信息进行归档一次,版本号依次递增.那么我们就要新建一张合同历史表, ...

  3. 利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理

    利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理   2018-3-10 15:18 | 发布:Admin | 分类:代码库 | 评论: ...

  4. Java利用反射排序

    前言 Java为我们提供了几种排序得方法,比如Arrays和Collections类,但是前提是数组或者集合中的元素都必须实现Comparable接口,基本的数据类型都已经实现了Comparable接 ...

  5. [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

    [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...

  6. <五>JDBC_利用反射及JDBC元数据编写通用的查询方法

    此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...:通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山! 一.使用JDBC驱动 ...

  7. 利用反射将Datatable、SqlDataReader转换成List模型

    1. DataTable转IList public class DataTableToList<T>whereT :new() { ///<summary> ///利用反射将D ...

  8. 利用反射及jdbc元数据实现通用的查询方法

    ---------------------------------------------------------------------------------------------------- ...

  9. 第十篇 一个利用反射实现的Excel导出

    前些天写了个导出Excel的公共类,因为项目中也需要上传Excel,没有利用Office组件,(PS:Office在上传文件时候,Excel进程无法关闭,会导致上传和打开失败)有的说利用Kill把进程 ...

随机推荐

  1. Linux下的sed命令使用详解

    sed是stream editor的简称,也就是流编辑器.它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”pattern space,接着用sed命令处理缓冲区中的内容, ...

  2. centos7 -lvm卷组

    老忘,记一下   基本的逻辑卷管理概念: PV(Physical Volume)- 物理卷 物理卷在逻辑卷管理中处于最底层,它可以是实际物理硬盘上的分区,也可以是整个物理硬盘,也可以是raid设备. ...

  3. 判断iframe页面是否是顶层页面

    if (self!=top) {  window.parent.location.reload();}

  4. eclipse——添加Tomcat7.0服务器

    首先要安装好Tomcat 然后在eclipse中添加Tomcat 步骤如下 详细可参考这篇博客https://blog.csdn.net/u014079773/article/details/5139 ...

  5. Android QRCodeReaderView 和Camera API冲突

    开发一款小功能,核心功能是二维码扫描,然后发送到远端服务器.App结构分为两个Activity,Activity A 负责二维码扫描,然后将参数存到本地,再启动Activity B,在Activity ...

  6. SqlServer、oracle、mysql分页的实现

    我们在编写MIS系统和Web应用程序等系统时,都涉及到与数据库的交互,如果数据库中数据量很大的话,一次检索所有的记录,会占用系统很大的资源,因此我们常常采用,需要多少数据就只从数据库中取多少条记录,即 ...

  7. Tomcat出现java.lang.Exception: Socket bind failed

    今天测试系统,Tomcat(apache-tomcat-6.0.20windows版)突然出现异常,导致JSP页面无法运行.错误提示如下:2014-3-12 17:13:29 org.apache.c ...

  8. scala学习手记32 - trait选择性混入

    继续上一节. 狗当然是人类的好朋友.但是藏獒呢?这玩意儿又蠢又笨又凶狠,肯定不能算很多人的好朋友了.其实,刚才那句话还可以修正一下下:我们接受的狗才是我们的好朋友. 用程序怎么实现呢?在java里面, ...

  9. angular components

    最近写了一套angular 组件,希望大家支持: Github: https://github.com/zhantewei2/ng-ztw webSite:http://39.108.193.57:3 ...

  10. 使用Java代码来创建view

    使用Java代码来创建view 一.简介 需要了解的知识 二.方法 1)java代码创建view方法 * 1.先建view对象 View view= View.inflate(this, R.layo ...