Pregunta

He descubierto (de manera difícil) que una colección que se enumera no puede modificarse dentro de "Foreach" declaración

  

" Se modificó la colección; la operación de enumeración puede no ejecutarse. "

Ahora, la solución que se me ocurrió es crear una colección ficticia del mismo tamaño que contenga una clave de diccionario y enumerarla para modificar la colección en cuestión.

    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();
    }

El código anterior funcionó bien; Estaba en proceso de refactorizar el código anterior para usar un delegado de Func para devolver una copia de las claves de la siguiente manera

    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();
    }

A diferencia de lo que esperaba, getNodeIds no devuelve una copia. ¿Hay alguna forma de devolver una copia?

* EDITAR : Resultado temporal antes de La respuesta de JaredPar

Similar a la respuesta de JaredPar, pero la suya fue más concisa y fui con su respuesta. Pero aquí está el resultado similar que se me ocurrió compartir.

    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();
    }

* EDITAR : Resultado final (refinado)

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

Solución

Simplemente agregue un .ToList () al final de la colección y automáticamente devolverá una copia completa de la lista.

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

Otros consejos

En lugar de usar un foreach, puedes usar un normal para. Sin embargo, tenga cuidado al agregar / eliminar elementos, ya que cambia los índices de los elementos dentro de la colección.

Una vez que cambie una clase Enumerable, su enumerador original puede dejar de ser válido, por lo que es necesario crear una copia y realizar sus modificaciones allí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top