3
\$\begingroup\$

Since I had been in the need of finding directories from a startpath with different search depth levels, I created this little helper class.

This class is using objects of the System.IO namespace.

public class IOHelper
{
    public const int AllDirectories = -1;
    public const int TopDirectoryOnly = 0;
    private const char WildCard = '*';

    public static IEnumerable<String> EnumerateDirectories(String startDirectory,  int depth)
    {
        return EnumerateDirectories(startDirectory, "*.*", depth);
    }

    public static IEnumerable<String> EnumerateDirectories(String startDirectory, String searchPattern, int depth)
    {
        if (depth < AllDirectories) { throw new ArgumentOutOfRangeException("depth", "Depth needs to be -1(AllDirectories) or greater"); }

        switch (depth)
        {
            case AllDirectories:
                return Directory.EnumerateDirectories(startDirectory, searchPattern, SearchOption.AllDirectories);

            case TopDirectoryOnly:
                return Directory.EnumerateDirectories(startDirectory, searchPattern, SearchOption.TopDirectoryOnly);

            default:
                return EnumerateDirectoriesInDepth(startDirectory, searchPattern, depth);
        }
    }

    private static IEnumerable<String> EnumerateDirectoriesInDepth(String startDirectory, String searchPattern, int depth)
    {
        IEnumerable<String> directories = EnumerateDirectoriesInDepth(startDirectory, depth);

        Boolean isWildCardSearch = searchPattern.Contains(WildCard);

        if (!isWildCardSearch)
        {
            searchPattern = String.Concat("\\", searchPattern);
            return directories.Where(d => d.EndsWith(searchPattern));
        }

        IEnumerable<String> enumeratedDirectories = Enumerable.Empty<String>();
        foreach (String directory in directories)
        {
            enumeratedDirectories = enumeratedDirectories.Concat(Directory.EnumerateDirectories(directory, searchPattern));
        }

        return enumeratedDirectories;
    }

    private static IEnumerable<String> EnumerateDirectoriesInDepth(String startDirectory, int depth)
    {
        if (depth <= TopDirectoryOnly) { return Enumerable.Empty<String>(); }

        IEnumerable<String> directories = Directory.EnumerateDirectories(startDirectory, "*.*", SearchOption.TopDirectoryOnly);

        if (!directories.Any()) { return directories; }

        depth = depth - 1;

        IEnumerable<String> subDirectories = Enumerable.Empty<String>();
        foreach (String directory in directories)
        {
            subDirectories = subDirectories.Concat(EnumerateDirectoriesInDepth(directory, depth));
        }

        return directories.Concat(subDirectories);
    }
}  

I would like to get a review on all aspects.

\$\endgroup\$
4
\$\begingroup\$

Since the class has only static and constant members, you should make the entire class static. It eliminates the unnecessary empty instance constructor the framework automatically generates. (see code analysis rules CA1052 and CA1053).

You should also generally use the type aliases provided (i.e., string instead of String, bool instead of Boolean, etc. - see StyleCop rule SA1121).

Additionally, I would change the recursion in EnumerateDirectoriesInDepth so it does not have to recurse another step when the depth is zero.

private static IEnumerable<string> EnumerateDirectoriesInDepth(string startDirectory, int depth)
{
    var directories = Directory.EnumerateDirectories(startDirectory, "*.*", SearchOption.TopDirectoryOnly);

    if (depth == TopDirectoryOnly || !directories.Any())
    {
        return directories;
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.