Как вернуть копию оригинального списка < T > от Func < T, TResult > ;?
Вопрос
Я обнаружил (сложным образом), что перечисляемая коллекция не может быть изменена в " 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, ваш исходный перечислитель может стать недействительным, поэтому вам придется создавать копию и вносить в нее изменения.