List<T>多字段排序的一个通用类

本文中的方法旨在解决通用的问题,非常注重效率的地方,还应该针对具体的类去写排序方法。

废话不多说,直接上代码

具体使用场景:

  • 要排序的类
 1         public class bb
 2         {
 3             public aa a { get; set; }
 4         }
 5 
 6         public class aa
 7         {
 8             public string index { get; set; }
 9             public string name { get; set; }
10 
11             public aa(string index, string name)
12             {
13                 this.index = index;
14                 this.name = name;
15             }
16         }
  • 使用CommentComparer类排序
 1             List<bb> list = new List<bb>()
 2             {
 3                 new bb(){a = new aa("13", "35")},
 4                 new bb(){a = new aa("14", "35")},
 5                 new bb(){a = new aa("12", "35")},
 6                 new bb(){a = new aa("14", "12")},
 7             };
 8 
 9             CommentComparer<bb> comparer = new CommentComparer<bb>();
10             //comparer.IsAsc = true;
11             //comparer.IsProperty = true;
12             comparer.AddField("a.index");
13             comparer.AddField("a.name");
14 
15             list.Sort(comparer);
  •  结果

 

CommentComparer类具体实现

  1     /// <summary>
  2     /// 排序类
  3     /// </summary>
  4     /// <typeparam name="T"></typeparam>
  5     public class CommentComparer<T> : IComparer<T>
  6     {
  7         /// <summary>
  8         /// 字段列表
  9         /// </summary>
 10         private List<string> fieldList;
 11 
 12         /// <summary>
 13         /// 排序字段序号
 14         /// </summary>
 15         private int index = 0;
 16 
 17         /// <summary>
 18         /// 正序
 19         /// </summary>
 20         public bool IsAsc { get; set; }
 21 
 22         /// <summary>
 23         /// 使用字段的属性排序
 24         /// <para>False:使用字段排序</para>
 25         /// </summary>
 26         public bool IsProperty { get; set; }
 27 
 28         public CommentComparer()
 29         {
 30             fieldList = new List<string>();
 31             IsAsc = true;
 32             IsProperty = true;
 33             index = 0;
 34         }
 35 
 36         /// <summary>
 37         /// 添加排序使用的字段
 38         /// </summary>
 39         /// <param name="fieldName"></param>
 40         public void AddField(string fieldName)
 41         {
 42             fieldList.Add(fieldName);
 43         }
 44 
 45         public int Compare(T x, T y)
 46         {
 47             if (x == null)
 48             {
 49                 if (y == null)
 50                 {
 51                     return 0;
 52                 }
 53 
 54                 return 1;
 55 
 56             }
 57             if (y == null)
 58             {
 59                 return -1;
 60             }
 61 
 62             int result = -1;
 63 
 64             if (fieldList.Count < 1)
 65             { throw new FormatException("请添加排序所使用的字段!"); }
 66             if (index == 0 && !IsAsc)
 67             {
 68                 T temp;
 69                 temp = y;
 70                 y = x;
 71                 x = temp;
 72             }
 73 
 74             string[] field = fieldList[index].Split('.');
 75 
 76             dynamic p1 = GetValue<T>(x, field, 0);
 77             dynamic p2 = GetValue<T>(y, field, 0);
 78 
 79             result = Comparer<string>.Default.Compare(p1, p2);
 80             if (result == 0)
 81             {
 82                 index++;
 83                 if (fieldList.Count > index)
 84                 { result = Compare(x, y); }
 85                 index--;
 86             }
 87             return result;
 88         }
 89 
 90         /// <summary>
 91         /// 获取属性值
 92         /// </summary>
 93         /// <typeparam name="T"></typeparam>
 94         /// <param name="obj"></param>
 95         /// <param name="field"></param>
 96         /// <param name="i"></param>
 97         /// <returns></returns>
 98         private dynamic GetValue<T>(T obj, string[] field, int i)
 99         {
100             dynamic result;
101 
102             Type t = typeof(T);
103 
104             if (IsProperty)
105             {
106                 PropertyInfo propertyInfo = t.GetProperty(field[i]);
107                 result = propertyInfo.GetValue(obj, null);
108             }
109             else
110             {
111                 FieldInfo fieldInfo = t.GetField(field[i]);
112                 result = fieldInfo.GetValue(obj);
113             }
114 
115             if (i < field.Length - 1)
116             {
117                 result = GetValue(result, field, ++i);
118             }
119             return result;
120         }
121     }

 

posted @ 2016-10-14 10:00  时嬴政  阅读(347)  评论(2编辑  收藏  举报