简体   繁体   English

创建 LINQ 表达式以获取 KeyedCollection 底部的正确属性

[英]Creating a LINQ expression to get the correct property at the bottom of a KeyedCollection

I'm having some issues refactoring and ordering a list.我在重构和排序列表时遇到了一些问题。

I have a class called DomainCollection which inherits from KeyedCollection .我有一个名为DomainCollection的 class,它继承自KeyedCollection

public class DomainCollection<T> : KeyedCollection<ID, T>, IDomainCollection<T> where T : class, IDomainObject

I created and filled a list called orders.我创建并填写了一个名为订单的列表。

var orders = new DomainCollection<Order>();

An order contains an OrderType which contains its own OrderTypes.一个订单包含一个 OrderType,它包含自己的 OrderType。 So if we were to have a condition where we can perform some actions, it would look like this因此,如果我们有一个可以执行某些操作的条件,它看起来像这样

if(order.Type.Type.Equals(OrderTypes.InvestmentToBankY))
{
  //Currently: logic where it creates a new list and adds the list to the existing order 
  //list and the very end. 
}

Onto my problem.关于我的问题。 I would like to be able to sort my order list so that my orders with InvestmentToBankY will be either at the bottom or top of my DomainCollection.我希望能够对我的订单列表进行排序,以便我的 InvestmentToBankY 订单将位于我的 DomainCollection 的底部或顶部。

If you just want to iterate over the elements having orders with InvestmentToBankY at the top, you can just use something like:如果您只想遍历顶部具有InvestmentToBankY订单的元素,您可以使用类似的东西:

// Add .ToList() if you want to materialize the items immediately.
var orderedOrders = 
    orders.OrderBy(o => o.Type.Type.Equals(OrderTypes.InvestmentToBankY));
foreach (var order in orderedOrders)
{
    // This will follow the desired order.
}

If you want to end up with a sorted DomainCollection , a not-so-efficient way to do so would be to reconstruct the DomainCollection using the new order.如果您想以排序的DomainCollection结束,那么一种不太有效的方法是使用新顺序重建DomainCollection Something like the following should work:像下面这样的东西应该工作:

public class DomainCollection<T> : KeyedCollection<ID, T>, IDomainCollection<T> 
    where T : class, IDomainObject
{
    public DomainCollection() { }

    public DomainCollection(IEnumerable<T> items)
    {
        foreach (var item in items)
            this.Add(item);
    }

    protected override ID GetKeyForItem(T item)
    {
        // TODO: implement GetKeyForItem.
        throw new NotImplementedException();
    }
}

Then, you can use it as follows:然后,您可以按如下方式使用它:

var orderedOrders = 
    orders.OrderBy(o => o.Type.Type.Equals(OrderTypes.InvestmentToBankY));

orders = new DomainCollection(orderedOrders);

A better solution that avoids creating a new collection is to rely on the fact that KeyedCollection inherits Collection<T> whose Items property is internally a List<T> and write our own sorting method that uses either a Comparison<T> or an IComparer<T> and calls the corresponding List<T>.Sort overload.避免创建新集合的更好解决方案是依赖于KeyedCollection继承Collection<T>的事实,其Items属性在内部List<T>并编写我们自己的排序方法,该方法使用Comparison<T>IComparer<T>并调用相应的List<T>.Sort重载。 Here's an example of the latter:这是后者的一个例子:

public class DomainCollection<T> : KeyedCollection<ID, T>, IDomainCollection<T> 
    where T : class, IDomainObject
{
    protected override ID GetKeyForItem(T item)
    {
        // TODO: implement GetKeyForItem.
        throw new NotImplementedException();
    }

    public void Sort(IComparer<T> comparer)
    {
        ((List<T>)this.Items).Sort(comparer);
    }
}

public class OrderComparer : IComparer<Order>
{
    public int Compare(Order x, Order y)
    {
        return x.Type.Type.Equals(OrderTypes.InvestmentToBankY).
            CompareTo(y.Type.Type.Equals(OrderTypes.InvestmentToBankY));
    }
}

Usage:用法:

orders.Sort(new OrderComparer());

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

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