繁体   English   中英

C#递归调用和数组

[英]C# Recursive Calls and Arrays

我坐在这里发现自己正在编写C#的递归调用以编写RegistryKey

我可以很容易地对它进行硬编码,但是我需要递归地进行编码。

using System;
using System.Collections.Generic;
using Microsoft.Win32;

private const string regKeyPath = @"Software\Apps\jp2code\net\TestApp";

static void Main() {
  string[] split = regKeyPath.Split('\\');
  RegistryKey key = null;
  try {
    keyMaker(Registry.LocalMachine, split);
  } finally {
    if (key != null) {
      key.Close();
    }
  }
  // continue on with Application.Run(new Form1());
}

因此, keyMaker是我想要成为我的递归函数的东西。

private static void keyMaker(RegistryKey key, string[] path) {
  string subKey = null;
  string[] subKeyNames = key.GetSubKeyNames();
  foreach (var item in subKeyNames) {
    if (path[0] == item) {
      subKey = item;
    }
  }
  RegistryKey key2 = null;
  try {
    if (String.IsNullOrEmpty(subKey)) {
      key2 = key.CreateSubKey(subKey);
    } else {
      key2 = key.OpenSubKey(subKey);
    }
    keyMaker(key2, &path[1]); // <= NOTE! Not allowed/defined in C#
  } finally {
    key2.Close();
  }
}

因此,我不能简单地从数组的下一个元素开始传递数组。

在C#中有没有一种巧妙的方法可以做到这一点?

注册表位与问题无关,只是将我的实际问题添加到阵列任务中。

一种简单的方法来更改方法的签名以包括起始索引:

void keyMaker(RegistryKey key, string[] path, int startIndex)

除此之外,还可以使用LinkedList<T>Queue<T>代替数组,并使用LinkedList<T>.RemoveFirst()Queue<T>.Dequeue()方法删除其head元素。

但是您根本不需要递归来解决此问题(除非这是一个练习)。

根据大声笑进行了编辑。

keyMaker(Registry.LocalMachine, ref split, 0);
....
private static void keyMaker(RegistryKey key, ref string[] path, int index) {
if( index > path.length - 1 ) return;
....
if (path[index] == item) {
....
keyMaker(key2, ref path, ++index);
....

不用递归就可以了。 考虑到密钥仅由CreateSubKey返回(如果存在),这就是我的写法:

private static void keyMaker(RegistryKey key, string[] path) {
    foreach(string subkey in path) {
        key = key.CreateSubKey(subkey);
    }
}

如果立即关闭它们很重要(我对此表示怀疑):

private static void keyMaker(RegistryKey key, string[] path) {
    RegistryKey lastKey = key;

    foreach(string subkey in path) {
        key = key.CreateSubKey(subkey);
        lastKey.Close();
        lastKey = key;
    }

    lastKey.Close();
}

尽管我更喜欢像@Groo建议的那样传递索引,但另一种可能性是使用IEnumerable<string>而不是string[]并使用LINQ。 在递归调用中,您可以传递path.Skip(1) ,它将从列表中删除第一个元素(或更准确地说,返回一个从第二个元素开始的新IEnumerable<string> )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM