Foreach, Linkedisney, Clóvis de Barros Filho e código que não funciona...
Eu tenho sérias críticas em relação ao Linkedisney - nome carinhoso dado ao Linkedin. É uma rede social contaminada por coaches e gurus, onde todas as empresas são ótimas, todas as startups vão se tornar unicórnios e todos os códigos postados funcionam. É o mundo da fantasia pseudo-corporativo-quântica! É bizarro! E pra piorar, cada vez mais aparecem na minha timeline "CTOs Coachs" (geralmente aquela figura que apenas comprou um domínio do godaddy ou subiu um site no wordpress com meia dúzia de plugins) com fórmulas revolucionárias de se entregar software no prazo (prazo não, time to market), com baixo custo, com qualidade e que vão revolucionar o dia a dia do consumidor. "Gestores" incríveis que sabem EXATAMENTE como manter as equipes (alguns chegam a dizer mais de 50) motivadas, produtivas e entregando valor! Apresentam gráficos lindos embasados em experiências duvidosas e enumeram n formas de como resolver todos os problemas possíveis dentro da sua empresa. (Criados nitidamente usando aquele prompt bem escrito, bonitinho, do jeito que o ChatGPT gosta!). Como diria Clóvis de Barros Filho: O guru tem a chave, que funciona pra qualquer um, seja você quem for: aplicou deu certo! #SóQueNão No final do ano de 2024, quando a Caixa Econômica Federal fez a Mega da Virada, o site precisou criar um sistema de fila on-line. Não vou entrar aqui no mérito de como poderia resolver isso (ou se deveriam resolver), até porque eu sozinho não conseguiria ter todas as respostas, mas a quantidade de "entendidos" que postaram besteiras sobre o assunto, fazendo afirmações totalmente descabidas, sem contexto nenhum, ou ainda, que tinham soluções pré-prontas para resolver todo e qualquer problema possível e imaginável, foi gigantesca. Teve um cidadão que propôs várias modificações no sistema da Caixa como a inclusão de Mensageria, Cache e refatoração do legado! Viu que simples? "Manda pra fila, processa e pronto!" (Coach do Linkedisney) Tá fácil... Eu tenho certeza de que em outras redes sociais isso aconteceu também, mas o Linkedin geralmente passa um ar "profissional", logo, para muitos, quem lá escreve, o faz com a razão e conhecimento de quem tem experiência suficiente para, de forma decisiva, definir o que é certo, errado e como fazer. Aplicou, funciona! Tem gente que cai nessa. Outro perfil que tem ganhado muita força é o influencer tiktoker tech, que na ânsia de postar o mais rápido possível, de gerar o máximo de conteúdo, de estar sempre no hype para ter mais e mais engajamento - o que a própria plataforma incentiva - acaba compartilhando qualquer coisa, ou pior, acaba gerando informações totalmente equivocadas, induzindo à aprendizagem errada por parte daqueles ou daquelas que estão começando na área. 35 super dicas para se tornar um desenvolvedor melhor! 197 plugins para turbinar seu VSCode! Não use Typescript! Não estude Python! Você programou errado a vida toda!!! Gifs, slide pdfs, desenhos de arquitetura, explicações (muitas vezes rasas e outras vezes completamente erradas) de determinada ferramenta ou patterns… todo esse tipo de “conteúdo” tem aumentado exponencialmente dia após dia. Minha timeline às vezes lembra o finado e saudoso Orkut de tanto gif piscando na tela. E é aí que mora o problema... a pressa é inimiga da compilação... A quantidade de coisas compartilhadas sem o mínimo cuidado, sem nenhuma revisão é de doer o pâncreas… Quer um exemplo disso que eu estou falando? Aí vai… Talvez você tenha visto essa pesquisa em sua timeline. Qual é o problema com esse código? A imagem mostra uma pesquisa do Linkedin perguntando qual é o resultado da execução do código csharp abaixo e com três opções de respostas: Infinite loop, 10 e 6. var numbers = new List { 1, 2, 3 }; foreach (var num in numbers) { numbers.Add(num * 2); if (numbers.Count > 10) break; } Compilou mentalmente o código? Conseguiu decifrar o enigma enigmático? Pega um café, eu te espero... Vem comigo!!! O problema é que esse código simplesmente não funciona! Ele compila, mas não funciona!!!: Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.Collections.Generic.List`1.Enumerator.MoveNext() at Program.$(String[] args) in /Volumes/SSD/Git/ForEach/ForEach/Program.cs:line 2 E se não funciona, logo, nenhuma das opções de respostas são válidas! A pessoa que propôs essa pesquisa nem sequer executou o código! E não... não foi uma pegadinha… analisando as respostas e outros posts do mesmo autor, chegamos facilmente à essa conclusão. Não é a primeira vez que vejo esse tipo de situação. É bastante comum encontrar exemplos de código que nem sequer compilam sendo apresentados como solução. Percebo que, muitas vezes, a pessoa simplesmente copia e cola diretamente do ChatGPT, sem ter a menor ideia do que está fazendo ou de como o código realmente funciona! Meu ponto aqui é reforçar a ideia de que o compartilham
Eu tenho sérias críticas em relação ao Linkedisney - nome carinhoso dado ao Linkedin. É uma rede social contaminada por coaches e gurus, onde todas as empresas são ótimas, todas as startups vão se tornar unicórnios e todos os códigos postados funcionam. É o mundo da fantasia pseudo-corporativo-quântica!
É bizarro!
E pra piorar, cada vez mais aparecem na minha timeline "CTOs Coachs" (geralmente aquela figura que apenas comprou um domínio do godaddy ou subiu um site no wordpress com meia dúzia de plugins) com fórmulas revolucionárias de se entregar software no prazo (prazo não, time to market), com baixo custo, com qualidade e que vão revolucionar o dia a dia do consumidor.
"Gestores" incríveis que sabem EXATAMENTE como manter as equipes (alguns chegam a dizer mais de 50) motivadas, produtivas e entregando valor!
Apresentam gráficos lindos embasados em experiências duvidosas e enumeram n formas de como resolver todos os problemas possíveis dentro da sua empresa. (Criados nitidamente usando aquele prompt bem escrito, bonitinho, do jeito que o ChatGPT gosta!).
Como diria Clóvis de Barros Filho:
O guru tem a chave, que funciona pra qualquer um, seja você quem for: aplicou deu certo!
#SóQueNão
No final do ano de 2024, quando a Caixa Econômica Federal fez a Mega da Virada, o site precisou criar um sistema de fila on-line. Não vou entrar aqui no mérito de como poderia resolver isso (ou se deveriam resolver), até porque eu sozinho não conseguiria ter todas as respostas, mas a quantidade de "entendidos" que postaram besteiras sobre o assunto, fazendo afirmações totalmente descabidas, sem contexto nenhum, ou ainda, que tinham soluções pré-prontas para resolver todo e qualquer problema possível e imaginável, foi gigantesca. Teve um cidadão que propôs várias modificações no sistema da Caixa como a inclusão de Mensageria, Cache e refatoração do legado! Viu que simples?
"Manda pra fila, processa e pronto!" (Coach do Linkedisney)
Tá fácil...
Eu tenho certeza de que em outras redes sociais isso aconteceu também, mas o Linkedin geralmente passa um ar "profissional", logo, para muitos, quem lá escreve, o faz com a razão e conhecimento de quem tem experiência suficiente para, de forma decisiva, definir o que é certo, errado e como fazer.
Aplicou, funciona!
Tem gente que cai nessa.
Outro perfil que tem ganhado muita força é o influencer tiktoker tech, que na ânsia de postar o mais rápido possível, de gerar o máximo de conteúdo, de estar sempre no hype para ter mais e mais engajamento - o que a própria plataforma incentiva - acaba compartilhando qualquer coisa, ou pior, acaba gerando informações totalmente equivocadas, induzindo à aprendizagem errada por parte daqueles ou daquelas que estão começando na área.
- 35 super dicas para se tornar um desenvolvedor melhor!
- 197 plugins para turbinar seu VSCode!
- Não use Typescript!
- Não estude Python!
- Você programou errado a vida toda!!!
Gifs, slide pdfs, desenhos de arquitetura, explicações (muitas vezes rasas e outras vezes completamente erradas) de determinada ferramenta ou patterns… todo esse tipo de “conteúdo” tem aumentado exponencialmente dia após dia.
Minha timeline às vezes lembra o finado e saudoso Orkut de tanto gif piscando na tela.
E é aí que mora o problema... a pressa é inimiga da compilação...
A quantidade de coisas compartilhadas sem o mínimo cuidado, sem nenhuma revisão é de doer o pâncreas…
Quer um exemplo disso que eu estou falando?
Aí vai…
Talvez você tenha visto essa pesquisa em sua timeline.
Qual é o problema com esse código?
A imagem mostra uma pesquisa do Linkedin perguntando qual é o resultado da execução do código csharp abaixo e com três opções de respostas: Infinite loop, 10 e 6.
var numbers = new List<int> { 1, 2, 3 };
foreach (var num in numbers)
{
numbers.Add(num * 2);
if (numbers.Count > 10) break;
}
Compilou mentalmente o código? Conseguiu decifrar o enigma enigmático?
Pega um café, eu te espero...
Vem comigo!!!
O problema é que esse código simplesmente não funciona! Ele compila, mas não funciona!!!:
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at Program.$(String[] args) in /Volumes/SSD/Git/ForEach/ForEach/Program.cs:line 2
E se não funciona, logo, nenhuma das opções de respostas são válidas!
A pessoa que propôs essa pesquisa nem sequer executou o código!
E não... não foi uma pegadinha… analisando as respostas e outros posts do mesmo autor, chegamos facilmente à essa conclusão.
Não é a primeira vez que vejo esse tipo de situação. É bastante comum encontrar exemplos de código que nem sequer compilam sendo apresentados como solução. Percebo que, muitas vezes, a pessoa simplesmente copia e cola diretamente do ChatGPT, sem ter a menor ideia do que está fazendo ou de como o código realmente funciona!
Meu ponto aqui é reforçar a ideia de que o compartilhamento de conteúdo precisa ser feito com responsabilidade. É uma atitude nobre, que merece atenção de quem produz e gratidão de quem consome!
Fazer por fazer, para ganhar seguidores, ou ter mais likes desvirtua totalmente o propósito de servir, de compartilhar para aprender e de aprender para ensinar.
Compartilhe aquilo que você sabe. Não hesite! Sempre vai ter alguém que vai se identificar com a forma como você escreve e/ou fala. E no final, você vai perceber que na verdade, cada compartilhamento gerou um conhecimento gigantesco para você e para a sua carreira. Mas tenha o cuidado de revisar tudo que está sendo publicado. Faz com carinho :)
Aliás, para que esse post não fique só na ladainha, bora falar sobre código?
Sendo assim, você consegue imaginar o motivo pelo qual o código acima lança exceção?
Não? Pega outro café então!
Toda vez que eu tenho alguma dúvida sobre como um determinado código funciona, eu utilizo o sharplab.io. Nesse site é possível ver como o código csharp ficou após sua compilação, isto é, o código csharp se torna IL e em seguida é feita uma engenharia reversa transformando IL em código csharp.
Com isso, podemos notar o tanto de açúcar sintático que existe no csharp. Não sabe o que é açúcar sintático? Eu fiz um post que fala sobre isso: https://dev.to/angelobelchior/por-debaixo-do-capo-c-e-acucar-sintatico-3gji. É um dos posts mais lidos do blog \o/
O código acima é transformado nesse código abaixo:
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
List<int> list2 = list;
List<int>.Enumerator enumerator = list2.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
int current = enumerator.Current;
list2.Add(current * 2);
if (list2.Count > 10)
{
break;
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
À primeira vista, notamos que o foreach
simplesmente não existe, ele é "substituído" pelo iterator pattern!
A idea desse pattern é permitir o acesso sequencial aos elementos de uma coleção sem expor sua implementação interna. Ele separa a lógica de iteração da lógica de armazenamento dos dados.
Por isso que nós podemos iterar num List
, LinkedList
, HashSet
, etc. usando foreach, porém cada classe dessa tem a sua própria forma de armazenar dados e percorrê-los ao ser iterado.
A implementação desse pattern passa por uma interface - IEnumerator
- contendo dois métodos e uma propriedade:
-
bool MoveNext();
: Avança o enumerador para o próximo elemento da coleção. Retorna verdadeiro se o enumerador avançou com sucesso para o próximo elemento; falso se o enumerador passou do fim da coleção -
object Current { get; }
: Obtém o elemento na coleção na posição atual do enumerador. -
void Reset();
: Define o enumerador para sua posição inicial, que é antes do primeiro elemento na coleção.
Olhando o código gerado acima, podemos notar claramente esse fluxo de looping de acesso sequencial através da iteração baseada em índice. Porém o código em si está isolado dentro da implementação específica da classe List
: https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/mscorlib/system/collections/generic/list.cs#L1140
Logo, a exceção InvalidOperationException
ao tentar modificar a lista durante a execução de um foreach
ocorre porque o "iterador" (enumerador) mantém um estado interno que pode ser invalidado quando a lista é modificada. E isso é evitado propositalmente!
Imagine que o índice de enumeração está na posição 5, caso um item fosse incluído ou removido, esse índice teria que ser recalculado. Não parece complexo isso, porém caso esse índice mude a todo instante poderemos ter comportamentos inesperados durante o loop como acessar itens que não existiam no início da iteração ou pular itens devido a alterações.
Por isso que o código quebra!
O código que efetua essa trava é bem simples. O foreach detecta modificações na coleção através da variável version:
private bool MoveNextRare()
{
if (version != list._version) { // <---- Validação da versão da lista
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
index = list._size + 1;
current = default(T);
return false;
}
public bool MoveNext() {
List<T> localList = list;
if (version == localList._version && ((uint)index < (uint)localList._size))
{
current = localList._items[index]; // acesso feito via índex
index++;
return true;
}
return MoveNextRare(); // <------ Método que valida o version da lista
}
Caso queira ler todo o código da classe List
, acesse
https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/mscorlib/system/collections/generic/list.cs#L1172.
A classe é grande, mas a diversão é garantida!
Aliás, recomendo muito ler o código fonte as classes base do csharp: https://github.com/microsoft/referencesource/tree/master/mscorlib/system. Esse é um exercício extraordinário. É possível aprender muito vasculhando esses códigos, e você vai perceber que não existe nada de mágico ou de paranormal... é apenas código csharp, bem escrito. Recomendo muito.
Era isso. Desculpa qualquer coisa.
Até a próxima!