0

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互いに正確に等しい 2 つのキーがあります。

誰かがここで何が起こっているのかを理解するのを助けることができますか?辞書に重複キーを持つことはどのように可能ですか??

ありがとう

4

1 に答える 1

1
    public int Compare(string X, string Y) 
    {  
        int nXSlashes = SlashCounter(X); 
        int nYSlashes = SlashCounter(Y); 

        if (nXSlashes > nYSlashes)
          return -1;
        if (nXSlashes < nYSlashes)
          return 1;

        return string.Compare(X, Y, true);          
    } 
于 2012-07-11T07:17:48.147 に答える