【原创+散分】逐步为对象集合构建一个通用的按指定属性排序的方法
有时候我们需要对集合中的自定义对象进行排序,以最原始的 System.Array 为例,如
Person[] people = new Person[]{ new Person(3, "Andy", new DateTime(1982, 10, 3)), new Person(1, "Tom", new DateTime(1993, 2, 10)), new Person(2, "Jerry", new DateTime(1988, 4, 23))};
class Person{ public int Id { get; set; } public string Name { get; set; } public DateTime Birthday { get; set; } public Person(int id, string name, DateTime birthday) { Id = id; Name = name; Birthday = birthday; } public override string ToString() { return String.Format("Id: {0,-6}Name: {1,-20}Birthday: {2:yyyy-MM-dd}", Id, Name, Birthday); }}
public static void Sort<T>( T[] array, Comparison<T> comparison)
static int CompareById(Person first, Person second){ if (first.Id > second.Id) return 1; if (first.Id == second.Id) return 0; return -1;}
Array.Sort(people, new Comparison<Person>(CompareById));
foreach (Person p in people) Console.WriteLine(p);
static int CompareById(Person first, Person second){ return first.Id.CompareTo(second.Id);}
Array.Sort(people, delegate(Person first, Person second){ return first.Id.CompareTo(second.Id);});
Array.Sort(people, (first, second) => first.Id.CompareTo(second.Id));
public static Comparison<Person> CompareByProperty(string name){ switch (name) { case "Id": return (first, second) => first.Id.CompareTo(second.Id); case "Name": return (first, second) => first.Name.CompareTo(second.Name); case "Birthday": return (first, second) => first.Birthday.CompareTo(second.Birthday); default: throw new Exception("属性 " + name + " 不存在。"); }}
Array.Sort(people, Person.CompareByProperty("Birthday"));
public static Comparison<Person> CompareByProperty(string name){ Type typeOfPerson = typeof(Person); PropertyInfo p = typeOfPerson.GetProperty(name); if (p == null) throw new Exception("属性 " + name + " 不存在。"); // 假定该类所有的属性均实现了接口 IComparable return (first, second) => ((IComparable)p.GetValue(first, null)).CompareTo(p.GetValue(second, null));}
public static Comparison<T> CompareByProperty<T>(string name){ Type typeOfPerson = typeof(T); PropertyInfo p = typeOfPerson.GetProperty(name); if (p == null) throw new Exception("属性 " + name + " 不存在。"); // 假定该类所有的属性均实现了接口 IComparable return (first, second) => ((IComparable)p.GetValue(first, null)).CompareTo(p.GetValue(second, null));}
Array.Sort(people, CompareByProperty<Person>("Name"));
static class ExtensionArray{ public static void SortBy(this Array array, string name) { Type elementType = array.GetType().GetElementType(); Type bridge = typeof(Bridge<>).MakeGenericType(elementType); MethodInfo sortMethod = bridge.GetMethod("Sort"); sortMethod.Invoke(null, new object[] { array, name }); } private static class Bridge<T> { private static Comparison<T> CompareByProperty(string name) //不必再是泛型方法 { Type typeOfPerson = typeof(T); PropertyInfo p = typeOfPerson.GetProperty(name); if (p == null) throw new Exception("属性 " + name + " 不存在。"); // 假定该类所有的属性均实现了接口 IComparable return (first, second) => ((IComparable)p.GetValue(first, null)).CompareTo(p.GetValue(second, null)); } public static void Sort(Array array, string name) { Array.Sort((T[])array, CompareByProperty(name)); } }}
people.SortBy("Birthday");
static class ExtensionArray { public enum Order { Ascending, Descending } public static void SortBy<T>(T[] array, string propName, Order order) { PropertyInfo pi = typeof(T).GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (pi == null) { throw new Exception("不存在名为" + propName + "的属性"); } else if (Array.IndexOf(pi.PropertyType.GetInterfaces(), typeof(IComparable)) < 0) { throw new Exception("属性" + propName + "没有实现IComparable接口"); } Array.Sort<T>(array, new Comparison<T>((t1, t2) => { var v1 = (IComparable)pi.GetValue(t1, null); var v2 = (IComparable)pi.GetValue(t2, null); return order == Order.Ascending ? v1.CompareTo(v2) : v2.CompareTo(v1); })); } } class Program { static void Main(string[] args) { Person[] people = new Person[]{ new Person(3, "Andy", new DateTime(1982, 10, 3)), new Person(1, "Tom", new DateTime(1993, 2, 10)), new Person(2, "Jerry", new DateTime(1988, 4, 23)) }; ExtensionArray.SortBy<Person>(people, "Birthday", ExtensionArray.Order.Descending); foreach (Person p in people) Console.WriteLine(p.ToString()); } class Person { public int Id { get; set; } public string Name { get; set; } public DateTime Birthday { get; set; } public Person(int id, string name, DateTime birthday) { Id = id; Name = name; Birthday = birthday; } public override string ToString() { return String.Format("Id: {0,-6}Name: {1,-20}Birthday: {2:yyyy-MM-dd}", Id, Name, Birthday); } } }
[解决办法]
学习
[解决办法]
[code=C#][/code]
[解决办法]
学习……
[解决办法]
好好学习
[解决办法]
学习!!
[解决办法]
支持原创,学习~
顶起来!
[解决办法]
参考,学习。!
[解决办法]
OK,CTRL+c,收藏了
[解决办法]
学习下
[解决办法]
学习过,谢谢哈
[解决办法]
很好,顶了
[解决办法]
学习贴!
[解决办法]
学习,学习!
[解决办法]
留待后看!
[解决办法]
[Serializable()] public class SortableBindingList<T> : BindingList<T>, ITypedList, IBindingListView {
[解决办法]
学习
[解决办法]
学习
[解决办法]
[解决办法]
好,支持
[解决办法]
向楼主学习!
[解决办法]
不懂,支持
[解决办法]
接分吧…
[解决办法]
DDDD!!!
[解决办法]
DDDD!!!
[解决办法]
值得学习!
[解决办法]
顶起来。。。
[解决办法]
学习
[解决办法]
学习 学习
[解决办法]
学习了~~
[解决办法]
关注
[解决办法]
关注ing。。。
[解决办法]
学习了,谢谢
[解决办法]
收藏
[解决办法]
看看,学习了,谢谢LZ
------解决方案--------------------
学习学习。
[解决办法]
学习学习。
[解决办法]
留名,再细看,学习
[解决办法]
顶
[解决办法]
学习 学习 在学习
[解决办法]
mark
[解决办法]
顶楼主的分享精神
[解决办法]
向楼主学习
[解决办法]
学习了
[解决办法]
不错的好帖,学习+收藏
[解决办法]
MArk
[解决办法]
学习
[解决办法]
学习
[解决办法]
学习了,谢谢
[解决办法]
学习学习
[解决办法]
楼的说得好,对于你个人来说,这样的收获会获益一辈子,
正所谓失败是成功之母,失败只不过是你成功的奠基石,LZ单枪匹马的干已经
很令人钦佩了
[解决办法]
[解决办法]
up
[解决办法]
支持
[解决办法]
mark
[解决办法]
收藏一个。
[解决办法]
UP一下,接分了。。。。。。
[解决办法]
帮顶,分析的不错
[解决办法]
支持原创。。。 支持散分。。。
[解决办法]
mark
[解决办法]
好好好
[解决办法]
学习,再学习!
[解决办法]
支持原创,学习!
up
[解决办法]
写的真好,学习中。
[解决办法]
支持一下
[解决办法]
不错,我很喜欢这样的氛围!
[解决办法]
学习。
[解决办法]
学习了,接分
[解决办法]
学习
我一般用arraylist de sort()方法
[解决办法]
学习
------解决方案--------------------
学习过。谢谢楼主。
[解决办法]
只能支持,并收藏了。
[解决办法]
还以为是java,哈哈
[解决办法]
学习,JF
[解决办法]
学习中
[解决办法]
好帖
[解决办法]
太好了。
[解决办法]
学习
[解决办法]
up