Начать с того, что указывать три предложения orderby
- плохая идея - вместо этого указывайте несколько порядков, просто используя запятую.
Я также не заинтересован в идее использования Randomiser.Next()
для заказа, но это в стороне.
Ваш запрос LINQ должен выглядеть следующим образом (все еще с Randomiser
на данный момент):
var query = (from PML in PossibleMoveLocations
orderby PossibleMoveLocationOrdering(PML),
IsSameType(PML) ? (_Owner[PML] as TileFlowing).UnitsWithin : 0,
Randomiser.Next()
select PML).ToList();
Лично я бы просто использовал для этого точечную запись:
var query = PossibleMoveLocations
.OrderBy(pml => PossibleMoveLocationOrdering(PML))
.ThenBy(pml => IsSameType(pml) ?
(_Owner[pml] as TileFlowing).UnitsWithin : 0)
.ThenBy(pml => Randomiser.Next())
.ToList();
Для сортировки на месте вам, в основном, нужен Comparison<T>
или IComparer<T>
, который может тестировать несколько вещей, а также реализация, которая создает компаратор с использованием свойств. Вы можете сделать это вручную (согласно коду Марка), но, как это происходит, у меня есть несколько вспомогательных классов и методов расширения в MiscUtil :
var comparer = ProjectionComparer<PossibleMove>
.Create(pml => PossibleMoveLocationOrdering(PML));
.ThenBy(pml => IsSameType(pml) ? ...)
.ThenBy(...);
list.Sort(comparer);
Обратите внимание, что использование Randomizer
здесь определенно плохая идея, так как она будет вызываться при каждом сравнении (для объектов с равными первыми частями) ... это может привести к противоречивому сравнению, например что x
<<code>y <<code>z <<code>x.