C# RegistryKey.GetSubKeyNames中元素的顺序

C# RegistryKey.GetSubKeyNames中元素的顺序,c#,.net,C#,.net,函数RegistryKey.GetSubKeyNames返回子键的顺序是什么?它们是按字母顺序排列的吗?或者,它们是否以某种随机顺序对应于它们在注册表中的存储 我已经做了多次搜索并检查了MSDN,但我还没有找到一个明确的答案。理想情况下,MSDN会声明键已排序或显式声明其顺序是随机的 我想知道的原因是我想编写代码来检测注册表中COM类的所有版本。它们会有13、14等名称。如果对键进行排序,我就可以找到第一个匹配的键,迭代所有匹配我的搜索,并在键不再匹配我的搜索时短路。这样我就不必遍历所有的子键。

函数
RegistryKey.GetSubKeyNames
返回子键的顺序是什么?它们是按字母顺序排列的吗?或者,它们是否以某种随机顺序对应于它们在注册表中的存储

我已经做了多次搜索并检查了MSDN,但我还没有找到一个明确的答案。理想情况下,MSDN会声明键已排序或显式声明其顺序是随机的


我想知道的原因是我想编写代码来检测注册表中COM类的所有版本。它们会有13、14等名称。如果对键进行排序,我就可以找到第一个匹配的键,迭代所有匹配我的搜索,并在键不再匹配我的搜索时短路。这样我就不必遍历所有的子键。

因为文档不保证任何特定的顺序,所以您不能假设任何特定的顺序。如果您需要特定的订单,您必须自行排序。(顺序不是随机的,但也不是排序的。)

我同意,如果没有文档,您不能假设某些东西,但很多时候文档可能是错误的、过时的或不存在的

因此,当JetBrains使用dotPeek并查看mscorlib.dll时,我们看到以下代码用于提取子关键字名称:

[SecuritySafeCritical]
Public String[] GetSubKeyNames()
{
  this.CheckPermission(RegistryKey.RegistryInternalCheck.CheckKeyReadPermission, (String) null, False, RegistryKeyPermissionCheck.Default);
  Return this.InternalGetSubKeyNames();
}

[SecurityCritical]
internal unsafe String[] InternalGetSubKeyNames()
{
  this.EnsureNotDisposed();
  Int length1 = this.InternalSubKeyCount();
  String[] strArray = New String[length1];
  If (length1 > 0)
  {
    Char[] chArray = New Char[256];
    fixed (Char* lpName = &chArray[0])
    {
      For (Int dwIndex = 0; dwIndex < length1; ++dwIndex)
      {
        Int length2 = chArray.Length;
        Int errorCode = Win32Native.RegEnumKeyEx(this.hkey, dwIndex, lpName, ref length2, (Int[]) null, (StringBuilder) null, (Int[]) null, (Long[]) null);
        If (errorCode != 0)
          this.Win32Error(errorCode, (String) null);
        strArray[dwIndex] = New String(lpName);
      }
    }
  }
  Return strArray;
}
[SecuritySafeCritical]
公共字符串[]GetSubKeyNames()
{
this.CheckPermission(RegistryKey.RegistryInternalCheck.CheckKeyReadPermission,(String)null,False,RegistryKeyPermissionCheck.Default);
返回这个.InternalGetSubKeyNames();
}
[证券评论]
内部不安全字符串[]InternalGetSubKeyNames()
{
这是一个;
Int length1=this.InternalSubKeyCount();
字符串[]strArray=新字符串[长度1];
如果(长度1>0)
{
Char[]chArray=新字符[256];
已修复(Char*lpName=&chArray[0])
{
对于(Int-dwIndex=0;dwIndex
因此-订单将始终使用RegEnumKeyEx函数。看看这里,我们看到“因为子键没有顺序,任何新的子键都会有一个任意的索引。这意味着函数可以以任何顺序返回子键。”


这是你的明确答案。

我不能说这是一个明确的答案,但当我试图为自己回答同样的问题时,我得出结论,这是存储顺序,即FIFO或自然顺序

我使用过的所有注册表编辑器都按字母顺序对键名和值名进行排序。这不是自然规律。RegScanner向我展示了HKLM\Software\Microsoft\Windows\CurrentVersion\Run的自然顺序


除了删除键中的所有值,然后按字母顺序将它们放回,我不知道有什么方法可以使自然顺序与字母顺序匹配。但是,如果稍后添加新值,则此顺序将被打破,因为新值将在末尾添加。

我将把缺少文档解释为“没有定义的顺序”。由于没有明确的文档,我建议假设该顺序是
未定义的
。您将返回一个
字符串[]
。您可以使用
Enumerable.OrderBy()
轻松地对它进行排序,如果它没有得到排序,我只需循环所有键就更有效了。这给了我一个最坏的情况O(n)的性能,而排序首先是O(n^2)或O(n log n),这取决于排序。一般来说,我认为这个答案是正确的。只是我不断发现MSDN上的文档是完全不充分的。这就是我问的原因。:)通常,如果MSDN未指定,则行为未指定。