元のリスト< 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 : JaredParの回答
JaredParの答えに似ていますが、彼はもっと簡潔で、私は彼の答えを使いました。 しかし、これは私が共有するために思いついた同様の結果です。
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();
}
*編集:最終結果(改良版)
_AuthenticatedNodes.Keys.ToList().ForEach(
nodeId => _AuthenticatedNodes[nodeId] = false);
解決
コレクションの最後に.ToList()を追加するだけで、リストの完全なコピーが自動的に返されます。
foreach (var nodeId in _AuthenticatedNodes.Keys.ToList())
...
他のヒント
foreachを使用する代わりに、通常のforを使用できます。ただし、アイテムを追加/削除するときは注意してください。コレクション内の要素のインデックスが変更されます。
Enumerableクラスを変更すると、元の列挙子が無効になる可能性があるため、コピーを作成してそこに変更を加える必要があります。
所属していません StackOverflow