Pergunta

Eu descobri (em uma maneira mais difícil) que uma coleção que está sendo enumerado não pode ser modificado dentro "Foreach" declaração

"coleção foi modificada;. Operação de enumeração não pode executar"

Agora, a solução que eu vim com é criar uma coleção fictícia do mesmo tamanho que contém uma chave de dicionário e enumerar sobre ele para modificar coleção em questão.

    private void InvalidateAuthenticatedNodes()
    {
        var dummy = new Dictionary<int, bool>(_AuthenticatedNodes.Count);
        foreach (var nodeId in _AuthenticatedNodes.Keys)
            dummy[nodeId] = false;

        foreach (var nodeId in dummy.Keys)
            _AuthenticatedNodes[nodeId] = false;

        ClearAuthenticatedDateTime();
    }

código acima funcionou bem; Eu estava no processo de refatoração acima de código para usar um delegado Func para retornar uma cópia de chaves da seguinte forma

    private void InvalidateAuthenticatedNodes()
    {
        var getNodeIds = 
            new Func<Dictionary<int, bool>, IEnumerable<int>>(
                nodes => nodes.Select(node => node.Key));
        foreach (var nodeId in getNodeIds(_AuthenticatedNodes))
        {
            _AuthenticatedNodes[nodeId] = false;
        }

        ClearAuthenticatedDateTime();
    }

Ao contrário do que eu esperava, getNodeIds não retorna uma cópia. Existe uma maneira para retornar uma cópia em vez disso?

* EDIT : resultado temporário antes de A resposta de JaredPar

Semelhante a resposta de JaredPar mas a sua foi mais conciso e eu fui com a sua resposta. Mas aqui é o resultado similar eu vim com a ação.

    private void InvalidateAuthenticatedNodes()
    {
        var getNodeIds = 
            new Func<Dictionary<int, bool>, IEnumerable<int>>(nodes => 
                nodes.Select(node => node.Key));
        foreach (var nodeId in getNodeIds(_AuthenticatedNodes).ToList())
        {
            _AuthenticatedNodes[nodeId] = false;
        }

        ClearAuthenticatedDateTime();
    }

* EDIT : Resultado Final (refinado)

_AuthenticatedNodes.Keys.ToList().ForEach(
    nodeId => _AuthenticatedNodes[nodeId] = false);
Foi útil?

Solução

Basta adicionar um .ToList () para o final da coleção e vai automagicamente devolver uma cópia completa da lista.

foreach (var nodeId in _AuthenticatedNodes.Keys.ToList())
    ...

Outras dicas

Em vez de usar um foreach, você poderia usar um normal para. No entanto, tenha cuidado ao adicionar / remover itens, muda os índices dos elementos dentro da coleção.

Uma vez que você alterar uma classe Enumerable, o recenseador original pode tornar-se inválido, portanto, a necessidade de criar uma cópia e fazer as modificações lá.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top