【发布时间】:2013-10-24 20:45:28
【问题描述】:
class Employee
{
public string Name {get;set;}
public int employee_id {get;set}
public int Age {get;set}
}
Class EmployeeCollection : IEnumerable, IEnumerable<Employee>, IOrderedEnumerable<Employee>
{
public Expression<Func<Employee, dynamic>> SortOrder {get;set;}
protected Dictionary<int,Employee> EmployeeById = new Dictionary<int,Employee>();
public void AddEmployee(Employee ePassed)
{
EmployeeById[ePassed.employee_id] = ePassed;
}
public IEnumerator<Employee> GetEnumerator()
{
foreach (int id in EmployeeByID.Keys)
{
yield return EmployeeById[id];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IOrderedEnumerable<Employee> CreateOrderedEnumerable<TKey>(Func<Employee, TKey> KeySelector, IComparer<TKey> comparer, bool descending)
{
if (descending)
return this.OrderByDescending(KeySelector, comparer);
else
return this.OrderBy(KeySelector, comparer);
}
public IEnumerable<Employee> OrderedObjects
{
if (this.SortOrder == null)
return (IEnumerable<Employee>)this; // No Sort Order applied
else
{
// How do I get the "parameters" from SortOrder to pass into CreateOrderedEnumerable?
throw new NotImplementedException();
}
}
}
我希望能够使用类似于以下的语法...
EmployeeCollection.SortOrder = (x => x.Name);
foreach (Employee e in EmployeeCollection.OrderedObjects)
{
// Do something in the selected order
}
有数千个示例说明如何将排序、过滤等结果放入新的列表、集合、ObservableCollection 等,但如果您现有的集合已经响应事件,则会自动添加新对象以响应通知、用户操作,来自服务器的新数据等,然后所有这些功能要么“丢失”,要么必须“添加”,以使新的 List、Collection、ObservableCollection 等监听原始集合,以便以某种方式与原始集合已经知道和处理的所有各种更新、属性等......我希望能够让原始的“EmployeeCollection”简单地在请求的 SortOrder 中分发“Employee”对象......
我对“SortOrder”属性的语法做了一个“疯狂的猜测”,因为我想让 SortOrder 属性的语法类似于团队中其他开发人员习惯使用的 lambda 表达式的 orderby 部分通过查看 System.Linq.Enumerable 中类似于以下内容的扩展方法:
public static IOrderedEnumerable<TSource> OrderBy<ToSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
我是 Linq、lambda 等的新手,如果我不知何故错过了 Linq/表达式树、谓词、匿名代表等其他人认为显而易见的关键方面,请提前道歉。
【问题讨论】:
-
这正是
EmployeeCollection.OrderBy(...)会做的事情,并且具有更方便的引导语法。这样做有什么问题? -
这样做的问题是 OrderBy() 扩展方法返回 IEnumerable
,它完全不知道原始 EmployeeCollection 的属性,没有连接到 EmployeeCollection 实现的 INotifyCollectionChanged 接口,等等等等……(你基本上得到了一个“愚蠢的对象列表”,它不知道如何做原始集合可以做的任何事情…… -
所以?原来的收藏还是知道的。如果它发生了什么事,那么你知道你必须再次重新计算排序视图。这是更多的工作,但显然不可能免费保持任何数量的排序视图与“原始”同步。您只能在急切同步它们(如果您事先知道所有这些,这从 q 中根本不清楚)或懒惰之间进行选择,如上所述。
标签: c# linq lambda sql-order-by iorderedenumerable