2012-01-11 2 views
0

Я сижу здесь, обнаружив, что я пишу рекурсивный вызов для C#, чтобы написать RegistryKey.C# Рекурсивные вызовы и массивы

Это то, что я мог бы жестко кодировать достаточно легко, но я бы сделал это рекурсивно.

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#?

Реестр бит не имеет ничего общего с проблемой, но для того, чтобы добавить проблему с реальным миром к задаче массива.

+0

Не уверен, что это выгодно для вас, но есть класс под названием «ArraySegment», который вы можете использовать для передачи оставшейся части массива путей (без выделения новых массивов и позволяет вернуться к оригиналу). – mpen

ответ

3

Простой способ быть, чтобы изменить подпись вашего метода, чтобы включить начальный индекс:

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

Кроме того, вы можете использовать LinkedList<T> или Queue<T> вместо массива, а также использовать LinkedList<T>.RemoveFirst() или Queue<T>.Dequeue() методы для снятия их головных элементов.

Но вам не нужна рекурсия, чтобы решить эту проблему вообще (если это не упражнение).

+0

Это это упражнение, в котором я не видел способа сделать это, используя 'string [] array'. Я никогда не думал о 'LinkedList ' или 'Queue '. Хорошие идеи! – jp2code

+1

K.I.S.S. - Я просто добавил значение индекса. – jp2code

1

Отредактировано в ответ на LOL.

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); 
.... 
+0

LOL - вы использовали незаконный '& path' в своем вызове' keyMaker', но я понимаю, что вы имели в виду под индексом. – jp2code

+1

Вам не нужно использовать 'ref'. Ссылка передается независимо. – Ryan

1

Не делайте этого рекурсивно - это все. Вот как я пишу это, учитывая, что ключ просто возвращаемый 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(); 
} 
+0

Мне это нравится. Это может быть так, как я иду, поэтому не меняйте его. Тем не менее, мне любопытно, как передать массив, учитывая массив. – jp2code

1

Хотя я d предпочитают передавать индекс, например, @Groo, другая возможность - использовать IEnumerable<string> вместо string[] и использовать LINQ. В рекурсивном вызове вы можете пройти path.Skip(1), который удалит первый элемент из списка (или, точнее, вернет новый IEnumerable<string>, который начинается со второго элемента).

+0

LINQ - Мне всегда приятно найти место, чтобы попробовать некоторые из них! – jp2code

Смежные вопросы