You can do it with simple recursive function to make it scalable. It receives array of items to combine, number of items to select from array and start index in array where to seleft items from (default to 0). It recursifely selects first item at every allowed starting position and attaches all combinations of further elements to the right in the items array.
public static IEnumerable<T[]> BuildCombinations<T>(T[] items, int itemsCountInCombination, int startIndex = 0)
{
if (itemsCountInCombination == 0)
{
yield return new T[0];
yield break;
}
for (int i = startIndex; i < items.Length; i++)
{
foreach (var combination in BuildCombinations(items, itemsCountInCombination - 1, i))
{
var c = new T[itemsCountInCombination];
c[0] = items[i];
Array.Copy(combination, 0, c, 1, combination.Length);
yield return c;
}
}
}
private static void Main(string[] args)
{
foreach (var c in BuildCombinations(Enum.GetValues(typeof (OrderedColors)).Cast<OrderedColors>().Reverse().ToArray(), 6))
{
foreach (var color in c)
{
Console.Write(color);
Console.Write(" ");
}
Console.WriteLine();
}
}
It generates the expected 924 combinations with repetition of 6 elements out of 7 in 0,44ms. It's probably not the best possible performance and it uses more memory than possible, but it's very simple implementation and efficient enough for such number of elements.