Finding a Cartesian product of multiple lists
You can indeed create a cartesian product without recursion. What you need is to use the enumerator.

I used a non-generic enumerator to work with any types.

public static IEnumerable Cartesian(this IEnumerable&lt;IEnumerable&gt; items)
{
    var slots = items
       // initialize enumerators
       .Select(x =&gt; x.GetEnumerator())
       // get only those that could start in case there is an empty collection
       .Where(x =&gt; x.MoveNext())
       .ToArray();

    while (true)
    {
        // yield current values
        yield return slots.Select(x =&gt; x.Current);

        // increase enumerators
        foreach (var slot in slots)
        {
            // reset the slot if it couldn't move next
            if (!slot.MoveNext())
            {
                // stop when the last enumerator resets
                if (slot == slots.Last()) { yield break; }
                slot.Reset();
                slot.MoveNext();
                // move to the next enumerator if this reseted
                continue;
            }
            // we could increase the current enumerator without reset so stop here
            break;
        }
    }
}


Example:

var letters = new string[] { "A", "B" };
var numbers = new[] { 1, 2, 3 };
var symbols = new[] { "@", "#" };
var empty = new string[] { };

var collections = new IEnumerable[] { letters, numbers, symbols, empty };
collections.Cartesian()
    // this is just for show
   .Select(x =&gt; string.Join("", x.Cast&lt;object&gt;()))
   .OrderBy(x =&gt; x)
   .Dump(); // linqpad


result:


A1# 
A1@ 
A2# 
A2@ 
A3# 
A3@ 
B1# 
B1@ 
B2# 
B2@ 
B3# 
B3@