Duvida em resolução de algoritmo utilizando C#

Tenho o seguinte código:

//LoadSources --- Os número dentro do método construtor é o id sendo inicializado

LoadSource ls1 = new LoadSource(530);
LoadSource ls2 = new LoadSource(550);
LoadSource ls3 = new LoadSource(580);

//Cases --- O mesmo para os Cases
Case cs1 = new Case("A1");
Case cs2 = new Case("B1");
Case cs3 = new Case("B2");
Case cs4 = new Case("C1");
Case cs5 = new Case("C2");

//Add Cases aos LoadSources
//O LoadSource 530 (ls1) só tem 1 case, os demais tem 2 cases
ls1.addCase(cs1);
ls2.addCase(cs2);
ls2.addCase(cs3);
ls3.addCase(cs4);
ls3.addCase(cs5);

//Lista dos LoadSources
List<LoadSource> lsList = new List<LoadSource>();

lsList.Add(ls1);
lsList.Add(ls2);
lsList.Add(ls3);

           /*
            *
            * Vocês têm uma lista de LoadSources e cada LoadSource possui uma lista de Cases (já configurado acima).
            * Com base nos dados criados acima, vocês devem gerar a seguinte matriz:
            *
            * 530[A1], 550[B1], 580[C1]
            * 530[A1], 550[B2], 580[C1]
            * 530[A1], 550[B1], 580[C2]
            * 530[A1], 550[B2], 580[C2]
            * 
            * Essa matriz é resultado da combinação dos Cases, conforme exemplificado abaixo:
            * 1, 1, 1
            * 1, 2, 1
            * 1, 1, 2
            * 1, 2, 2
            *
            */

O que fiz, mas não está saindo o resultado esperado… Ele está pegando um LoadSource e lista todos os seus cases em seguida. (O que não é o correto), gostaria de uma ajuda

foreach (var ls in lsList)
            {
                foreach (var cs in ls.caseList)
                {
                    Console.Write("{0} [{1}] ", ls.id, cs.id);
                }
            }

EDIT

No caso, tenho que imprimir os loadsources seguido dos seus cases na seguinte ordem:

530[A1], 550[B1], 580[C1]
530[A1], 550[B2], 580[C1]
530[A1], 550[B1], 580[C2]
530[A1], 550[B2], 580[C2]

*Entenda que o número fora do colchetes [] é o ID do LoadSource e o número dentro do colchetes [] é o ID do Case…

o LoadSource de ID 530, tem apenas 1 case, o LoadSource de ID 550 tem 2 cases e o LoadSource de ID 580 tbm tem 2 cases…

Com isso, teria que listar nesta sequência mostrada acima utilizando o princípio da permutação.

Não sei C#, acredito que usar recursão seria mais fácil:

void imprimir(lista, indice, sucessor)
{
	ls = lista[indice]
	foreach(case de ls)
	{
		resultado = string(ls, case) + sucessor;
		if (indice == 0)
		{
			console.imprimir(resultado);
		}
		else
		{
			
			imprimir(lista, indice - 1, resultado);
		}
	}
}

imprimir(lista, lista.size - 1, "");

Obrigado pela ajuda, mas uma dúvida, na assinatura desse método imprimir, a lista eu tenho aqui, no caso é um List<LoadSource> lsList

Já o índice e sucesso, seria o que no contexto que vc aplicou?

O “índice” para pegar o elemento (LoadSource) da lista, esse algoritmo deve correr do ultimo para o primeiro.

LoadSource ls = lista[indice];

O “sucessor” é o resultado da string formada a direita. Por correr do ultimo para o primeiro, a string será construída da direita para esquerda, talvez não seja um bom nome, mas não consegui pensar num melhor.

// resultado atual = formato string de ls com o case +
// + o que vem a direita calculado anteriormente pela recursão
resultado = string(ls, case) + sucessor;
// o resultado será o sucessor na próxima iteração se não for o primeiro
void imprimir(List<LoadSource> lsList, int sucessor)
    {
        var ls = lsList.Count;

        foreach (var lsItem in lsList)
        {
            foreach (var cs in lsItem.caseList)
            {
                var resultado = (lsItem.id + cs.id).ToString() + sucessor;

                if (lsList.Count == 0)
                    Console.Write(resultado);

                else
                    imprimir(lsList, resultado);
            }
        }
    }

Fiz dessa forma utilizando C#, será que está correto? (Fiz algumas alterações)

Não sei, não tenho compilador C#, teste e verifica se fez certo.

refiz o pseudocódigo com comentários e nome melhor

void imprimir(listaDeLoadSource, indiceDoLoadSourceAtual, stringResultante)
{
	// obtem o loadSource atual
	loadSourceAtual = listaDeLoadSource.Get(indiceDoLoadSourceAtual);
	// para cada case no loadSource atual
	foreach(case in loadSourceAtual.caseList)
	{
		// constroi nova string resultante
		novaStringResultante = to_string(loadSourceAtual, case) + stringResultante;
		// se o load source for o primeiro (indice == 0)
		if (indiceDoLoadSourceAtual == 0)
		{
			// imprime no console a nova string resultante (seria a linha)
			console.imprimir(novaStringResultante);
		}
		else
		{
			// senão repete, o proximo loadSource é o anterior ao atual (indiceDoLoadSourceAtual - 1)
			imprimir(listaDeLoadSource, indiceDoLoadSourceAtual - 1, novaStringResultante);
		}
	}
}

// começa do ultimo loadSource (lista.size - 1)
// a string resultante é inicialmente vazia ("")
imprimir(lista, lista.size - 1, "");