class Employee { public int Id { get; set; } public String Name { get; set; } public int Age { get; set; } }
//以Employee的Name字段为比较规则的比较器 class EmployeeNameComparer:IComparer<Employee> { public int Compare(Employee x, Employee y) { return StringComparer.CurrentCulture.Compare(x.Name, y.Name); } }
我们构造了一个EmployeeNameComparer类型,当我们这样使用SortedList<Employee>的时候:
//记录Employee电话号码的数据结构(虽然这么做有点傻,不过为了举例子还是将就一下吧)
var empTelTable = new SortedDictionary<Employee, String>(new EmployeeNameComparer());
这个比较器类型可以指示SortedList,我们希望它以何种方式比较两个Employee对象。
//以Employee的Age字段为比较规则的比较器 class EmployeeAgeComparer:IComparer<Employee> { public int Compare(Employee x, Employee y) { return x.Age - y.Age; } }
//以Employee的Id字段为比较规则的比较器 class EmployeeIdComparer:IComparer<Employee> { public int Compare(Employee x, Employee y) { return x.Id - y.Id; } }
EmployeeAgeComparer与EmployeeIdComparer的代码几乎一样。作为DRY(Don‘t Repeart Yourself)原则的忠实维护者,我们是不希望这样几乎一模一样的两份代码出现在我们的项目中的。因此是时候想办法重构了。
public class DelegatedComparer<T> : IComparer<T> { //在构造函数结束后,_compare就没法改变了。因此DelegatedComparer<T>实例的行为也就可以被锁定了。 private readonly Func<T, T, int> _compare; //传入一个委托,表示比较算法。 public DelegatedComparer(Func<T, T, int> func) { _compare = func; } public int Compare(T x, T y) { //直接调用委托。 return _compare(x, y); } }
//记录Employee电话号码的数据结构(虽然这么做有点傻,不过为了举例子还是将就一下吧) var empTelTable = new SortedDictionary<Employee, String>( new DelegatedComparer<Employee>( (x, y) => x.Id - y.Id) );
使用起来也非常简单!打字都少了很多吧? :-)