Get files recursively as relative paths I want to get a recursive list of files in a directory but I want relative paths and not the full paths that Directory.GetDirectories() would return using the AllDirectories search option. This is because I want to move the list of files to another location and perform a custom check on each file. I could try converting each absolute path to a relative path but that's a bit messy, so I decided to create a recursive function that generates relative paths as it goes.

public static string[] GetRelativeFilesRecursive(string path)
{
    IEnumerable&lt;string&gt; GetRelativeFilesRecursive(string basePath, string subFolder)
    {
        IEnumerable&lt;string&gt; getRelativeArray(Func&lt;string, IEnumerable&lt;string&gt;&gt; func)
        {
            return func(Path.Combine(basePath, subFolder)).Select(file =&gt; Path.Combine(subFolder, Path.GetFileName(file)));
        }

        IEnumerable&lt;string&gt; files = getRelativeArray(Directory.GetFiles);
        IEnumerable&lt;string&gt; directories = getRelativeArray(Directory.GetDirectories);

        foreach (string directory in directories)
        {
            files = files.Concat(GetRelativeFilesRecursive(basePath, directory));
        }

        return files;
    }

    return GetRelativeFilesRecursive(path, "").ToArray();
}


I'm using nested functions to make it more modular, i.e. I'd rather have one function that I can copy and paste as a whole than have multiple functions that could become separated. I'm using IEnumerable&lt;string&gt; instead of string[] because otherwise I'd have to call ToArray() on every Concat() call and I'm worried that would be bad for performance.

What do you think? Is this a good way to do this?
Building on Henrick's answer, using Ling to return the IEnumerable:

return Directory.GetFiles(root, "*", SearchOption.AllDirectories)
              .Select(p =&gt; p.Remove(0, rootLength));