简体   繁体   English

如何从基于OrderBy“属性”的集合中返回IOrderedEnumerable

[英]How can I return an IOrderedEnumerable from a Collection based on OrderBy “property”

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();
        }
    }
}

I want to be able to use syntax similar to the following... 我希望能够使用类似于以下内容的语法...

EmployeeCollection.SortOrder = (x => x.Name);
foreach (Employee e in EmployeeCollection.OrderedObjects)
{
  // Do something in the selected order
}

There are thousands of examples of how to throw sorted, filtered, etc results into a new List, Collection, ObservableCollection, etc. but if your existing collection already responds to events, automatically adds new objects in response to notifications, user actions, new data coming in from server, etc then all that functionality is either "lost" or has to be "added" to make the new List, Collection, ObservableCollection, etc. listen to the original collection in order to somehow stay in sync with all of the various updates, properties, etc that the original Collection ALREADY KNOWS ABOUT and handles... I want to be able to have the ORIGINAL "EmployeeCollection" simply dish out the "Employee" objects in the requested SortOrder... 有成千上万个如何将排序,过滤后的结果放入新的List,Collection,ObservableCollection等的示例,但是如果您现有的集合已经响应事件,则会自动添加新对象以响应通知,用户操作,新数据来自服务器等),那么所有功能要么“丢失”,要么必须被“添加”,以使新的List,Collection,ObservableCollection等能够侦听原始集合,以某种方式与所有原始集合已经了解并处理的各种更新,属性等...我希望能够使原始的“ EmployeeCollection”简单地在所请求的SortOrder中抛出“ Employee”对象。

I made a "wild ass guess" about the syntax for the "SortOrder" property based on wanting to make the syntax of the SortOrder property similar to the orderby portion of lambda expressions that other developers on the team are used to working with by looking at the extension methods in System.Linq.Enumerable similar to the following: public static IOrderedEnumerable<TSource> OrderBy<ToSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector); 我想对“ SortOrder”属性的语法进行“野蛮猜测”,其原因是希望使SortOrder属性的语法类似于lambda表达式的orderby部分,该团队其他开发人员习惯于通过查看System.Linq.Enumerable中的扩展方法类似于以下内容: public static IOrderedEnumerable<TSource> OrderBy<ToSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

I am new to Linq, lambda, etc and apologize in advance if I somehow missed some key aspect of Linq/Expression Trees,Predicates,anonymous delegates, etc that others consider obvious. 我是Linq,lambda等的新手,如果我因某种原因错过了Linq / Expression Trees,谓词,匿名代表等某些关键方面,而其他人则认为很明显,请向我道歉。

This works when you don't use ThenBy -type operations (which are all the IOrderedEnumerable<T> interface really adds). 当您不使用ThenBy -type操作( IOrderedEnumerable<T>接口真正添加的所有操作)时,此方法有效。 See C#: How to implement IOrderedEnumerable<T> for a solution to support that. 请参见C#:如何实现IOrderedEnumerable <T>以获得支持该解决方案的解决方案。

public class Employee
{
    public string Name {get;set;}
    public int employee_id {get;set;}
    public int Age {get;set;}
}

public class EmployeeCollection : IEnumerable, IEnumerable<Employee>, IOrderedEnumerable<Employee>
{
    public Func<Employee, object> SortOrder {get;set;}
    public Func<Employee, bool> Filter {get;set;}
    protected Dictionary<int,Employee> EmployeeById = new Dictionary<int,Employee>();
    public void Add(Employee ePassed)
    {
        EmployeeById[ePassed.employee_id] = ePassed;
    }
    public IEnumerator<Employee> GetEnumerator()
    {
        var employees = EmployeeById.Keys.Select(id => this.GetEmployee(id));
        if (Filter != null)
            employees = employees.Where(Filter);
        if (SortOrder != null)
            employees = employees.OrderBy(SortOrder);
        return employees.GetEnumerator();
    }
    public Employee GetEmployee(int id)
    {
        return EmployeeById[id];
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
      return this.GetEnumerator();
    }
    public IOrderedEnumerable<Employee> CreateOrderedEnumerable<TKey>(Func<Employee, TKey> KeySelector, IComparer<TKey> comparer, bool descending)
    {
      throw new NotImplementedException();
    }
}

// this is some code you might use to test this:
var EmployeeCollection = new EmployeeCollection
{
    new Employee { employee_id = 1, Age = 20, Name = "Joe" },
    new Employee { employee_id = 2, Age = 30, Name = "Thomas" },
    new Employee { employee_id = 3, Age = 25, Name = "Robert" },
};
EmployeeCollection.SortOrder = x => x.Age;
EmployeeCollection.Filter = x => x.Name.Length > 4;
foreach (Employee e in EmployeeCollection)
{
    // do something
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM