Reputation: 963
I have this method that extends IList<> for special ordering I need to implement. It takes an IList of IDisplayOrderable
and an integer forRandom
, and returns an ordered list but randomizing the items that have the DisplayOrder
equals to the forRandom
parameter.
public static IList<IDisplayOrderable> ReorderList(this IList<IDisplayOrderable> lstMain, int forRandom)
{
List<IDisplayOrderable> result = new List<IDisplayOrderable>();
Random rnd = new Random();
result.AddRange(lstMain.Where(x => x.DisplayOrder.GetValueOrDefault(int.MaxValue) < forRandom).OrderBy(x => x.DisplayOrder.GetValueOrDefault(int.MaxValue)));
result.AddRange(lstMain.Where(x => x.DisplayOrder.GetValueOrDefault(int.MaxValue) == forRandom).Shuffle(rnd));
result.AddRange(lstMain.Where(x => x.DisplayOrder.GetValueOrDefault(int.MaxValue) > forRandom).OrderBy(x => x.DisplayOrder.GetValueOrDefault(int.MaxValue)));
return result;
}
The IDisplayOrderable
is a simple interface that expose the DisplayOrder
for ordering different types.
public interface IDisplayOrderable
{
Nullable<int> DisplayOrder { get; set; }
}
I want to achieve the same functionality but for a generic list that I wish to explicit set the 'OrderBy' property,
something like:MyList.ReorderList(x=>x.DisplayOrder, 1000)
but also MyOtherList.ReorderList(x=>x.OtherDisplayOrder, 1000)
.
I read some about reflection to do this but haven't managed to get something working.
Any help or direction would be appreciated
Upvotes: 1
Views: 75
Reputation: 10476
Change ReorderList
method so that it accepts a delegate returning the value of your desired property:
public static IList<T> ReorderList(this IList<T> lstMain,Func<T,int?> getter, int forRandom)
{
List<T> result = new List<T>();
Random rnd = new Random();
result.AddRange(lstMain.Where(x => getter(x).GetValueOrDefault(int.MaxValue) < forRandom).OrderBy(x => getter(x).GetValueOrDefault(int.MaxValue)));
result.AddRange(lstMain.Where(x => x.getter(x).GetValueOrDefault(int.MaxValue) == forRandom).Shuffle(rnd));
result.AddRange(lstMain.Where(x => getter(x).GetValueOrDefault(int.MaxValue) > forRandom).OrderBy(x => xgetter(x).GetValueOrDefault(int.MaxValue)));
return result;
}
and call it like:
MyOtherList.ReorderList(x=>x.OtherDisplayOrder, 1000)
Upvotes: 2