111,093
社区成员




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");
public static class Extensions
{
public static void SortByPropertyName<T>(this T[] array, string propName)
{
Array.Sort(array, Inner<T>.GetComparison(propName));
}
private static class Inner<T>
{
private static Dictionary<string, Comparison<T>> m_cache = new Dictionary<string, Comparison<T>>();
internal static Comparison<T> GetComparison(string propName)
{
Comparison<T> comparison;
if (!m_cache.TryGetValue(propName, out comparison))
m_cache[propName] = comparison = GetComparisonNoCache(propName);
return comparison;
}
private static Comparison<T> GetComparisonNoCache(string propName)
{
var prop = typeof(T).GetProperty(propName);
var comparerType = typeof(Comparer<>).MakeGenericType(prop.PropertyType);
DynamicMethod dm = new DynamicMethod(string.Empty, typeof(int), new Type[] { typeof(T), typeof(T) }, typeof(T));
var il = dm.GetILGenerator();
il.Emit(OpCodes.Call, comparerType.GetProperty("Default").GetGetMethod());
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, prop.GetGetMethod());
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Callvirt, prop.GetGetMethod());
il.Emit(OpCodes.Callvirt, comparerType.GetMethod("Compare"));
il.Emit(OpCodes.Ret);
return (Comparison<T>)dm.CreateDelegate(typeof(Comparison<T>));
}
}
}