Question

J'ai découvert (de manière difficile) qu'une collection énumérée ne peut pas être modifiée dans "Foreach". déclaration

  

" La collection a été modifiée; l'opération d'énumération peut ne pas s'exécuter. "

Maintenant, la solution que j'ai proposée consiste à créer une collection factice de la même taille qui contient une clé de dictionnaire et à l'énumérer pour modifier la collection en question.

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

Le code ci-dessus a bien fonctionné. J'étais en train de refactoriser le code ci-dessus pour utiliser un délégué Func afin de renvoyer une copie des clés comme suit

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

Contrairement à ce à quoi je m'attendais, getNodeIds ne renvoie pas de copie. Est-il possible de retourner une copie à la place?

* EDIT : résultat temporaire avant Réponse de JaredPar

Similaire à la réponse de JaredPar mais la sienne était plus concise et je suis allé avec sa réponse. Mais voici le résultat similaire que je suis venu partager.

    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 : Résultat final (raffiné)

_AuthenticatedNodes.Keys.ToList().ForEach(
    nodeId => _AuthenticatedNodes[nodeId] = false);
Était-ce utile?

La solution

Ajoutez simplement un .ToList () à la fin de la collection et il retournera automatiquement une copie complète de la liste.

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

Autres conseils

Au lieu d’utiliser un foreach, vous pouvez utiliser un normal pour. Cependant, soyez prudent lorsque vous ajoutez / supprimez des éléments, les index des éléments de la collection sont modifiés.

Une fois que vous avez modifié une classe Enumerable, votre énumérateur d'origine peut devenir invalide, d'où la nécessité de créer une copie et d'y apporter vos modifications.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top