所以我有一个程序,它开始使用精确数量的步骤构建从给定起点到同一点的可能路径字典。
我首先为开始和结束步骤的每个独特组合添加一个字典行,然后我有一个方法,它基本上可以找到所有可以填充其间剩余步骤的独特组合。
它看起来像这样:
private int CreatePathsWithAllSteps(int pathKey)
{
try
{
//Make sure we reiterate through the list of paths for all the configured steps to complete the paths.
for (int i = 0; i < MaxSteps - 2; i++)
{
//Create a fresh list of new paths with each complete iteration so we're not duplicating added paths
Dictionary<int, TravelPath> newPaths = new Dictionary<int, TravelPath>();
foreach (KeyValuePair<int, TravelPath> path in Paths)
{
//We need to find the list of Destination Pairs we can use with the existing path
Dictionary<string, DestinationPair> pairsToUse = FindDestinationPairsToUseNext(path, i+1);
bool isfirstiteration = true;
//***Issue*** 1 - Creating the copy of the KVP so I can reuse it to create all possible combinations of it with the next step in the path.
//I use the values of the KVP from the dictionary i'm iterating through. This seems to create them as reference paths back to the original dictionary.
KeyValuePair<int, TravelPath> pathCopy = new KeyValuePair<int, TravelPath>(path.Key, path.Value);
foreach (KeyValuePair<string, DestinationPair> TP in pairsToUse)
{
//Make sure we're using already existing paths first and then create new ones for all other options.
if (isfirstiteration)
{
//First time through use path already created at this point
if (path.Value.Path[i].Name != TP.Value.Name)
{
//Destination Pair is different to the previous pair so add it
path.Value.Path[i + 1] = TP.Value;
isfirstiteration = false;
}
}
else
{
//for this one, create a new copy of the path we're working on and then update with next step
if (pathCopy.Value.Path[i].Name != TP.Value.Name)
{
//***Issue*** 2 - When I use the value of the copied KVP to create a new KVP to add to the dictionary this also seems to create a reference back to the copy and by extension the original value from the original dictionary we're iterating through.
KeyValuePair<int, TravelPath> tempTP = new KeyValuePair<int, TravelPath>(pathKey, pathCopy.Value);
//***Issue*** 3 - I then edit the value of the KVP created in the previous line, and this changes the value in the original main Paths dictionary.
tempTP.Value.Path[i + 1] = TP.Value;
if (!PathValueComparer(tempTP, newPaths, Paths))
{
newPaths.Add(pathKey, pathCopy.Value);
pathKey++;
}
}
}
}
}
foreach(KeyValuePair<int, TravelPath> path in newPaths)
{
Paths.Add(path.Key, path.Value);
}
}
return pathKey;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return pathKey;
}
}
我已经添加了一些带有***Issue***
前缀的额外注释,这样您就可以看到我认为问题出在哪里以及我认为这里发生了什么。
现在距离我上次进行常规编码已经 3 或 4 年了,所以我有点生疏了(请不要过多地判断我的代码,哈哈),但我确实记得以前在处理字典时遇到过类似的问题,而且我似乎请记住,解决方案是拥有一个实现 IDictionary 和 ICloneable 的自定义字典,因此您可以调用.Clone()
创建一个未引用的副本,然后可以对字典进行临时编辑并使用这些值,而不会将它们引用回您的源字典。
我想我会尝试用 KVP 做一些类似的事情,但似乎没有一个 KVP 接口可以实际用作自定义实现的基础。
我觉得我可能只是创建一个可克隆的字典,然后在从克隆版本中获取我需要的 KVP 副本之前克隆它,但是对于这项工作,我真的不需要整个字典都是可克隆的,只是KVP,所以看起来有点浪费
所以我想问题是,有没有更好的方法来打破 KVP 和 Dictionary 的值之间的引用?