0
我正在學習在C#中使用多態,但無法弄清楚這一點。我正在嘗試編寫一個允許我從存儲庫中獲取文件過濾列表的類。多態搜索文件系統或彙編嵌入式資源中的文件
存儲庫可以是文件系統文件夾或任意已加載程序集中的嵌入式資源(但不是當前正在執行的程序集)。
有什麼建議嗎?
我正在學習在C#中使用多態,但無法弄清楚這一點。我正在嘗試編寫一個允許我從存儲庫中獲取文件過濾列表的類。多態搜索文件系統或彙編嵌入式資源中的文件
存儲庫可以是文件系統文件夾或任意已加載程序集中的嵌入式資源(但不是當前正在執行的程序集)。
有什麼建議嗎?
您可以定義對接口這樣的:
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
}
然後你可以寫你的算法只依賴於這些接口而不是他們的實現。
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();
}
}
}
這是一個粗糙的例子,但應該指向你在正確的方向:)
尼爾森,我明白你的代碼。但是它並沒有解決困難的部分:我如何從傳遞一個字符串到具有可以調用方法的Assembly對象?如何避免在每次調用時加載該程序集,如果它已經加載? – 2009-01-20 03:47:51