Simple File Manager with recursion in C# Simple class to simpify runtime file loading of ressources. The class reads all files from a given directory including all subdirectories and stores the name together with the path in a simple struct. If a file needs to be used by the program just pass the name to GetPath() and the class returns the location of the file. 

Any suggestions/improvements about my implementation of this? Im especially not sure if making this static is the right choice.

using System.IO;
using System.Collections.Generic;

namespace Sample
{
    struct File
    {
        public string Name;
        public string Path;           
    }

    static class FileManager
    {        
        private static List&lt;File&gt; Files = new List&lt;File&gt;();        

        public static void AddFiles(string directory)
        {
            foreach(string file in  Directory.GetFiles(directory))
            {   
                Files.Add(new File() { Name = Path.GetFileName(file), Path = directory });
            }

            foreach(string subdirectory in Directory.GetDirectories(directory))
            {
                AddFiles(subdirectory);
            }
        }

        public static string GetPath(string filename)
        {
            var File = Files.Find(x =&gt; x.Name == filename);

            return File.Path;
        }

        public static void ClearFiles()
        {
            Files.Clear();
        } 
    }    
}
I don't think I would make this class static, unless it's going to be used extensively throughout the program. If not you can build up a large list of files, that may hang around in memory for no use, unless you remember to call ClearFiles(). Instead you could make a static method that could return an initialized object like:

public static FileManager Create(string directoryPath)
{
  FileManager fm = new FileManager();
  fm.AddFiles(directoryPath);
  return fm;
}


If you have a need for it, then make this instance as static somewhere in the application.




public static string GetPath(string filename)
{
  var File = Files.Find(x =&gt; x.Name == filename);
  return File.Path;
}



It returns only a first match of possible more matches, which will be in a directory high in the hierarchy, but what if you actually seek a path to a file in a subdirectory?

I think I would return a list/array/IEnumerable instead and let the client filter as needed.

Besides that, file names are case insensitive, so you should do:

Files.Find(x =&gt; string.Equals(x.Name, filename, StringComparison.CurrentCultureIgnoreCase));





public static void AddFiles(string directory)
{
  foreach (string file in Directory.GetFiles(directory))
  {
    Files.Add(new File() { Name = Path.GetFileName(file), Path = directory });
  }
  foreach (string subdirectory in Directory.GetDirectories(directory))
  {
    AddFiles(subdirectory);
  }
}



Nice recursive method. As an alternative you could consider to use DirectoryInfo instead - it can handle the recursive search for you:

  DirectoryInfo directory = new DirectoryInfo(directoryPath);
  Files.AddRange(
    directory
    .GetFiles("*.*", SearchOption.AllDirectories)
    .Select(fi =&gt; new File { Name = fi.Name, Path = fi.DirectoryName }));




There is no way to iterate through all the found File objects because the Files static member is private. I would consider to provide a public IEnumerable of some kind.



All in all, my implementation would look something like:

  public struct File
  {
    public string Name;
    public string Path;

    public override string ToString()
    {
      return $"{Name} =&gt; {Path}";
    }
  }

  public class FileManager : IEnumerable&lt;File&gt;
  {
    private List&lt;File&gt; Files = new List&lt;File&gt;();

    public void AddFiles(string directoryPath)
    {
      DirectoryInfo directory = new DirectoryInfo(directoryPath);
      Files.AddRange(
        directory
        .GetFiles("*.*", SearchOption.AllDirectories)
        .Select(fi =&gt; new File { Name = fi.Name, Path = fi.DirectoryName }));
    }

    public IEnumerable&lt;string&gt; GetPaths(string filename)
    {
      return Files
        .Where(x =&gt; string.Equals(x.Name, filename, StringComparison.CurrentCultureIgnoreCase))
        .Select(f =&gt; f.Path);
    }

    public void Clear()
    {
      Files.Clear();
    }

    public IEnumerator&lt;File&gt; GetEnumerator()
    {
      return Files.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
      return GetEnumerator();
    }

    public static FileManager Create(string directoryPath)
    {
      FileManager fm = new FileManager();
      fm.AddFiles(directoryPath);
      return fm;
    }
  }