I'm having some issues refactoring and ordering a list.
I have a class called DomainCollection
which inherits from 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. 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.
CodePudding user response:
If you just want to iterate over the elements having orders with InvestmentToBankY
at the top, you can just use something like:
// 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. 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. 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());