0
我正在嘗試創建一個SortedDictionary
,其中的鍵是一個表示文件/文件夾路徑的字符串。我正在嘗試根據路徑深度對該字典進行排序。我的標準只是檢查每個路徑中斜線的數量,並在字典的開頭放置斜線最多的路徑。IComparer和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();
}
}
}
在主要結束()_dExcludedPaths
將有兩個鍵它正好彼此相等的。
有人可以幫助理解這裏發生了什麼,以及如何有可能在字典中重複鍵?
感謝
它的工作..但你能解釋這是怎麼從我實現不同??? – 2012-07-11 07:43:15
@RedSerpent原始版本不是可交換函數:cmp(x,y)!= -cmp(y,x) – 2012-07-11 08:36:44
謝謝,我還想知道爲什麼字典有兩次列出相同的密鑰?我認爲這應該會導致例外.. – 2012-07-11 08:56:30