ricerca polimorfica di file nel file system o in risorse incorporate in assembly
-
19-08-2019 - |
Domanda
Sto imparando a usare il polimorfismo in C #, ma non riesco a capire questo. Sto cercando di scrivere una classe che mi consenta di ottenere un elenco filtrato di file da un repository.
Il repository potrebbe essere una cartella del file system o le risorse incorporate in un assembly arbitrario già caricato (ma non è quello attualmente in esecuzione).
Qualche suggerimento?
Soluzione
È possibile definire una coppia di interfacce in questo modo:
public interface IReadableFile
{
Stream OpenRead();
}
public interface IRepository
{
IEnumerable<IReadableFile> Search(string pattern);
}
E ne hanno due diverse implementazioni:
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
}
E poi puoi scrivere i tuoi algoritmi dipendenti solo da queste interfacce e non dalle loro implementazioni.
Altri suggerimenti
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();
}
}
}
Questo è un esempio approssimativo, ma dovrebbe indirizzarti nella giusta direzione :)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow