使用字典代替List - 获取ith条目

Ale*_*der 2 c# dictionary while-loop

也许我现在只是在愚蠢的时刻.我有以下内容:

List<DirectoryEntry> list = new List<DirectoryEntry>();
List.Add(startEntry);
int i=0;
while(i < list.Count) {
    DirectoryEntry entry = list[i];
    foreach(DirectoryEntry child in GetChildEntries(entry)) {
        if(!list.Contains(child)) // Do not add if entry already in list!
            list.Add(child);
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为Contains以两种方式为指向同一AD对象的directoryEntries返回false.

所以我想从那里创建一个Dictionary并将distinguishedName和条目一起存储:

Dictionary<string,DirectoryEntry> list = new Dictionary<string,DirectoryEntry>();
List.Add(startEntry.Properties["distinguishedName"].Value,startEntry);
int i=0;
while(i < list.Count) {
    DirectoryEntry entry = list[i]; // Does not work, because the index is a string here.
                                    // How to get the ith entry from the dictionary?
    foreach(DirectoryEntry child in GetChildEntries(entry)) {
        var dn = child.Properties["distinguishedName"].Value;
        if(!list.ContainsKey(dn)) list.Add(dn,child);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题,如代码评论中所述:

如何从字典中获取第i个条目?

Jon*_*eet 6

那么你可以使用list.ElementAt(i)来获得我在它们的顺序元素发生由字典返回-但有没有保证,以什么样的顺序是,或者说,它会留一段时间保持一致.我强烈建议避免考虑字典有任何秩序的概念.

在我看来,你只需要迭代字典:

foreach (var entry in list)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这导致了另一个问题,虽然,这是你正在修改你遍历集合,而你遍历它,它就会失败.您可能需要考虑在迭代时创建字典,然后将所有条目添加到原始字典中.

目前还不清楚你是否真的想要一本字典.我们不知道你真正想要实现的目标 - 这里有很多不同的选择.

编辑:如果你想扁平,你可以做类似的事情:

var entries = new Dictionary<string, DirectoryEntry>();
var queue = new Queue<DirectoryEntry>();
queue.Enqueue(startEntry);
while (queue.Count > 0)
{
    var candidate = queue.Dequeue();
    string key = candidate.Properties["distinguishedName"].Value;
    if (!entries.ContainsKey(key))
    {
        entries[key] = candidate;
        foreach (var child in GetChildEntries(candidate))
        {
            queue.Enqueue(child);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以foreach通过创建自己的EnqueueAll扩展方法来"隐藏" 循环Queue<T>.

这让我感觉更容易理解,而不是迭代你仍在添加的集合.

编辑:如果你不需要通过专有名称稍后再查看时,您可以使用HashSet<DirectoryEntry>一个自定义相等比较:

var entries = new HashSet<DirectoryEntry>(new DirectoryEntryEqualityComparer());
var queue = new Queue<DirectoryEntry>();
queue.Enqueue(startEntry);
while (queue.Count > 0)
{
    if (entries.Add(candidate))
    {
        foreach (var child in GetChildEntries(candidate))
        {
            queue.Enqueue(child);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)