我正在尝试创建一个SortedDictionary
其键是代表文件/文件夹路径的字符串。我正在尝试根据路径深度对该字典进行排序。我的标准只是检查每个路径中的斜杠数量,并将斜杠最多的路径放在字典的开头。
我的问题是,对于一些我无法检测到的奇怪问题,字典可以有多个完全相同的键。经过数小时的调试后的问题似乎是“有时”我的实现在调用方法或向字典添加新值时IComparer
不会遍历字典中的所有条目。ContainsKey
我没有得到例外或任何东西。
这是我的代码..(有点长):
namespace ConsoleApplication1
{
class DepthComparer : IComparer<string>
{
public int Compare(string X, string Y)
{
//Sort From deepest to shallowest
//C:\Users\NAME\Desktop\Folder\ should precede C:\Users\NAME\Desktop\
//Paths with same root level are ignored
int nXSlashes = SlashCounter(X);
int nYSlashes = SlashCounter(Y);
if (string.Compare(X, Y, true) == 0) //same path
{
return 0;
}
//Put Deepest Path at the beginning
return (nXSlashes > nYSlashes ? -1 : 1);
}
public int SlashCounter(string stPath)
{
int nSlashes = 0;
for (int i = 0; i < stPath.Length - 1; ++i)
{
if (stPath[i] == ('/') || stPath[i] == ('\\'))
nSlashes++;
}
return nSlashes;
}
}
public class ScanOptions
{
public enum ExcludeRule
{
Invalid = 0x00,
File = 0x01,
Folder = 0x02,
FileFolder = File | Folder,
}
private SortedDictionary<string, ExcludeRule> _dExcludedPaths;
public ScanOptions()
{
_dExcludedPaths = null;
}
//Creates a new Excluded Paths List (Automatically clears the current list if its already initialized)
public void CreateExcludedPathsList()
{
if (_dExcludedPaths == null)
_dExcludedPaths = new SortedDictionary<string, ExcludeRule>(new DepthComparer());
else
ClearExcludedPathsList();
}
public void ClearExcludedPathsList()
{
_dExcludedPaths.Clear();
}
public bool IsExcludedPathsListInitialized()
{
return _dExcludedPaths != null ? true : false;
}
public void AddExcludePath(string stPath, ExcludeRule Rule)
{
if (!IsExcludedPathsListInitialized())
return;
if (string.IsNullOrEmpty(stPath) || Rule == ExcludeRule.Invalid)
return;
string stTmp = stPath.ToLower();
try
{
if (stTmp.EndsWith("\\"))
{
stTmp = stTmp.Remove(stTmp.Length - 1);
}
if (_dExcludedPaths.ContainsKey(stTmp))
{
ExcludeRule OldRule = ExcludeRule.Invalid;
if (_dExcludedPaths.TryGetValue(stTmp, out OldRule))
{
if ((OldRule & Rule) == 0)
_dExcludedPaths[stTmp] |= Rule; //Same path new rule, append rule to existing one
}
return;
}
else
{
//brand new entry
_dExcludedPaths[stTmp] = Rule;
}
}
catch
{
}
}
public void AddExcludePaths(List<string> ExcludePaths, ExcludeRule Rule)
{
if (!IsExcludedPathsListInitialized())
return;
foreach (string stPath in ExcludePaths)
AddExcludePath(stPath, Rule);
}
public void AddExcludePaths(SortedDictionary<string, ExcludeRule> ExcludePaths)
{
if (!IsExcludedPathsListInitialized())
return;
foreach (KeyValuePair<string, ExcludeRule> PathRule in ExcludePaths)
AddExcludePath(PathRule.Key, PathRule.Value);
}
public void ShowInConsole()
{
foreach (KeyValuePair<string, ScanOptions.ExcludeRule> Rule in _dExcludedPaths)
{
Console.WriteLine(Rule.Key + "\t" + Rule.Value);
}
}
}
class Program
{
static void Main(string[] args)
{
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
//Fill a new string list with some paths
List<string> ExcludedPaths = new List<string>();
string ExPath = desktopPath + "\\12345678\\";
ExcludedPaths.Add(ExPath);
ExPath = desktopPath + "\\abcdefg\\";
ExcludedPaths.Add(ExPath);
ExPath = desktopPath + "\\ABCDEFG\\";
ExcludedPaths.Add(ExPath);
ExPath = desktopPath + "\\1A2B3C 4D5E6F\\123456\\4567896\\";
ExcludedPaths.Add(ExPath);
ExPath = desktopPath + "\\CDEVQWER ASD\\456786\\";
ExcludedPaths.Add(ExPath);
//Create the exclude list object
ScanOptions scanOpt = new ScanOptions();
scanOpt.CreateExcludedPathsList();
//First manually add one of the paths from the list above
scanOpt.AddExcludePath(desktopPath + "\\12345678\\", ScanOptions.ExcludeRule.Folder);
//Now add the whole list of paths to the exclude list in scan options
scanOpt.AddExcludePaths(ExcludedPaths, ScanOptions.ExcludeRule.Folder);
//Now add the first entry a couple more times with different value each time
scanOpt.AddExcludePath(desktopPath + "\\12345678\\", ScanOptions.ExcludeRule.File);
scanOpt.AddExcludePath(desktopPath + "\\12345678\\", ScanOptions.ExcludeRule.Folder);
//Dump the list to console
//We now have two keys in the dictionary that equal desktopPath + "\\12345678\\"
scanOpt.ShowInConsole();
}
}
}
在 Main() 的末尾_dExcludedPaths
将有两个完全相等的键。
有人可以帮助理解这里发生了什么以及字典中怎么可能有重复的键?
谢谢