我正在学习在C#中使用多态,但无法弄清楚这一点。我正在尝试编写一个允许我从存储库中获取过滤文件列表的类。
存储库可以是文件系统文件夹,也可以是任意已加载程序集中的嵌入资源(但它不是当前正在执行的程序集)。
有什么建议吗?
答案 0 :(得分:3)
您可以像这样定义一对接口:
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
}
然后你可以编写你的算法只依赖于这些接口而不是它们的实现。
答案 1 :(得分:0)
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();
}
}
}
这是一个粗略的例子,但应该指出正确的方向:)