полиморфный поиск файлов в файловой системе или во встроенных ресурсах сборки - PullRequest
0 голосов
/ 20 января 2009

Я учусь использовать полиморфизм в C #, но не могу понять это. Я пытаюсь написать класс, который позволяет мне получить отфильтрованный список файлов из хранилища.

Хранилище может быть папкой файловой системы или встроенными ресурсами в произвольной уже загруженной сборке (но это не та, которая выполняется в данный момент).

Есть предложения?

Ответы [ 2 ]

3 голосов
/ 20 января 2009

Вы можете определить пару интерфейсов следующим образом:

public interface IReadableFile
{
    Stream OpenRead();
}

public interface IRepository
{
    IEnumerable<IReadableFile> Search(string pattern);
}

И у них есть две разные реализации:

public class FolderFile : IReadableFile
{
    readonly private string _name;

    public FolderFile(string name)
    {
        _name = name;
    }

    #region IFile Members

    public Stream OpenRead()
    {
        return File.OpenRead(_name);
    }

    #endregion
}

public class FolderRepository : IRepository
{
    readonly private string _directory;

    public FolderRepository(string directory)
    {
        _directory = directory;
    }

    #region IRepository Members

    public IEnumerable<IReadableFile> Search(string pattern)
    {
        return Array.ConvertAll(Directory.GetFiles(_directory, pattern), name => new FolderFile(name));
    }

    #endregion
}

public class AssemblyFile : IReadableFile
{
    readonly private Assembly _assembly;
    readonly private string _name;

    public AssemblyFile(Assembly assembly, string name)
    {
        _assembly = assembly;
        _name = name;
    }

    #region IReadableFile Members

    public Stream OpenRead()
    {
        return _assembly.GetManifestResourceStream(_name);
    }

    #endregion
}

public class AssemblyRepository : IRepository
{
    readonly private Assembly _assembly;

    public AssemblyRepository(Assembly assembly)
    {
        _assembly = assembly;
    }

    #region IRepository Members

    public IEnumerable<IReadableFile> Search(string pattern)
    {
        return _assembly.GetManifestResourceNames().Where(name => name.Contains(pattern)).Select(name => new AssemblyFile(_assembly, name)).ToArray();
    }

    #endregion
}

И тогда вы можете написать свои алгоритмы, зависящие только от этих интерфейсов, а не от их реализаций.

0 голосов
/ 20 января 2009
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace Reposes
{
    class ReposeFile
    {
        string m_name;

        public string Name
        {
            get { return m_name; }
        }

        public ReposeFile(string name)
        {
            m_name = name;
        }
    }

    interface IRepose
    {
        void RetriveFiles();
        ReposeFile[] Files { get; }
    }

    class FileSystemRepose : IRepose
    {
        string m_path = null;
        List<ReposeFile> m_files = new List<ReposeFile>();

        public FileSystemRepose(string path)
        {
            m_path = path;
        }

        #region IRepose Members

        public void RetriveFiles()
        {
            string[] files = Directory.GetFiles(m_path);
            foreach (string file in files)
            {
                m_files.Add(new ReposeFile(file));
            }
        }

        public ReposeFile[] Files
        {
            get { return m_files.ToArray(); }
        }

        #endregion
    }

    class AssemblyRepose : IRepose
    {
        string m_assembly = null;
        List<ReposeFile> m_files = new List<ReposeFile>();

        public AssemblyRepose(string assembly)
        {
            m_assembly = assembly;
        }

        #region IRepose Members

        public void RetriveFiles()
        {
            m_files.Add(new ReposeFile("Stuff"));
        }

        public ReposeFile[] Files
        {
            get { return m_files.ToArray(); }
        }

        #endregion
    }

    class Consumer
    {
        static void Main()
        {
            List<IRepose> reps = new List<IRepose>();
            reps.Add(new FileSystemRepose("c:\\")); // would normally be @"c:\" but stackoverflow's syntax highlighter barfed :)
            reps.Add(new AssemblyRepose("rep.dll"));

            foreach (IRepose rep in reps)
            {
                rep.RetriveFiles();

                foreach (ReposeFile file in rep.Files)
                {
                    Console.WriteLine(file.Name);
                }
            }

            Console.ReadKey();
        }
    }
}

Это грубый пример, но он должен указать вам правильное направление:)

...