Как вернуть копию оригинального списка < T > от Func < T, TResult > ;?

StackOverflow https://stackoverflow.com/questions/615310

Вопрос

Я обнаружил (сложным образом), что перечисляемая коллекция не может быть изменена в " Foreach " Заявление

  

" Коллекция была изменена; операция перечисления может не выполняться. "

Итак, решение, которое я придумала, состоит в создании фиктивной коллекции того же размера, которая содержит ключ словаря, и ее перечисление для изменения рассматриваемой коллекции.

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

Выше код работал нормально; Я занимался рефакторингом приведенного выше кода, чтобы использовать делегат Func для возврата копии ключей следующим образом

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

В отличие от того, что я ожидал, getNodeIds не возвращает копию. Есть ли способ вернуть копию?

* EDIT : временный результат до ответ Джареда Пара

Аналогично ответу ДжаредПара, но он был более кратким, и я согласился с его ответом. Но вот схожий результат, который я придумал, чтобы поделиться.

    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 . Окончательный результат (уточнено)

_AuthenticatedNodes.Keys.ToList().ForEach(
    nodeId => _AuthenticatedNodes[nodeId] = false);
Это было полезно?

Решение

Просто добавьте .ToList () в конец коллекции, и он автоматически вернет полную копию списка.

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

Другие советы

Вместо использования foreach, вы можете использовать обычный для. Однако будьте осторожны при добавлении / удалении элементов, это меняет индексы элементов внутри коллекции.

После того, как вы измените класс Enumerable, ваш исходный перечислитель может стать недействительным, поэтому вам придется создавать копию и вносить в нее изменения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top