public static void Main()
var none = Array.Empty<string>();
new[] {none, new[] {"Product1"}, new[] {"Product1", "Product1"}},
new[] {none, new[] {"Product2", "Product2"}, new[] {"Product2", "Product2", "Product2"}},
new[] {none, new[] {"Product3"}, new[] {"Product3", "Product3"}},
static void print(string[][] strings)
foreach (var set in strings.Where(set => set.Length > 0))
Console.Write(string.Join(", ", set) + "; ");
public static void Combine<T>(T[][] sets, Action<T[]> output)
combine(sets, 0, new T[sets.Length], output);
static void combine<T>(T[][] sets, int set, T[] combination, Action<T[]> output)
for (int i = 0; i < sets[set].Length; ++i)
combination[set] = sets[set][i];
if (set < (sets.Length - 1))
combine(sets, set + 1, combination, output);