Eu o encontro frequentemente durante a programação em que quero ter um índice de contagem de loop dentro de um foreach e preciso criar um número inteiro, usá-lo, incrementar etc. Não seria uma boa idéia se houvesse uma palavra-chave introduzida que fosse a contagem de loop dentro de um foreach? Também pode ser usado em outros loops.
Isso vai contra o uso de palavras-chave, visto que o compilador não permitiria que essa palavra-chave fosse usada em outro lugar, exceto em uma construção de loop?
for ()
loop.Respostas:
Se você precisa de uma contagem de loop dentro de um
foreach
loop, por que não usa apenas umfor
loop regular ? Oforeach
loop foi projetado parafor
simplificar o uso específico de loops. Parece que você tem uma situação em que a simplicidadeforeach
não é mais benéfica.fonte
IEnumerable.Count
pode ser caro (ou impossível, se for uma enumeração única). Você precisa saber qual é a fonte subjacente antes de poder fazer isso com segurança.foreach
excessofor (int i = 0…)
. Ele escreveu algumas páginas, mas posso resumir em duas palavras - otimização do compilador na iteração. Ok, não foram duas palavras.for
loop fornece código melhor legível (e a otimização teórica do compilador geralmente é otimização prematura).Você pode usar tipos anônimos como este
Isso é semelhante à
enumerate
função do Pythonfonte
Estou apenas adicionando a resposta de Dan Finch aqui, conforme solicitado.
Não me dê pontos, dê pontos para Dan Finch :-)
A solução é escrever o seguinte método de extensão genérico:
Que é usado assim:
fonte
Posso estar errado sobre isso, mas sempre achei que o ponto principal do loop foreach era simplificar a iteração dos dias STL do C ++, ou seja,
compare isso com o uso do .NET de IEnumerable no foreach
o último é muito mais simples e evita muitas das antigas armadilhas. Além disso, eles parecem seguir regras quase idênticas. Por exemplo, você não pode alterar o conteúdo IEnumerable enquanto estiver dentro do loop (o que faz muito mais sentido se você pensar na maneira STL). No entanto, o loop for geralmente tem um propósito lógico diferente da iteração.
fonte
for(IEnumerator e=collection.GetEnumerator;e.MoveNext();) { ... }
Se a coleção em questão for uma
IList<T>
, você pode simplesmente usarfor
com a indexação:Caso contrário, você pode usar
Select()
, ele possui uma sobrecarga que fornece o índice.Se isso também não é adequado, acho que manter esse índice manualmente é bastante simples, são apenas duas linhas muito curtas de código. Criar uma palavra-chave especificamente para isso seria um exagero.
fonte
foo(++i)
oufoo(i++)
dependendo de qual índice é necessário.Se tudo o que você sabe é que a coleção é um IEnumerable, mas precisa acompanhar quantos elementos você processou até o momento (e, portanto, o total quando terminar), você pode adicionar algumas linhas a um loop for básico:
Você também pode adicionar uma variável de índice incrementada a um foreach:
Se você deseja que isso pareça mais elegante, você pode definir um método de extensão ou dois para "ocultar" esses detalhes:
fonte
O escopo também funciona se você deseja manter o bloco limpo de colisões com outros nomes ...
fonte
Para isso eu uso um
while
loop. Os loopsfor
também funcionam, e muitas pessoas parecem preferi-los, mas eu só gosto de usarfor
algo que terá um número fixo de iterações.IEnumerable
s podem ser gerados em tempo de execução, portanto, na minha opinião,while
faz mais sentido. Chame de orientação informal de codificação, se quiser.fonte