我有一组类,每个类都可以使用外部应用程序打开不同类型的文件,并告诉该应用程序将文件打印到特定的打印机.这些类都继承了一个公共抽象类和一个接口.
internal interface IApplicationPrinter : IDisposable
{
string ApplicationExe { get; }
string ApplicationName { get; }
string[] PrintableExtensions { get; }
IApplicationPrinter CreateInstance(string Filename, string Printer);
void Print();
bool ExitApplicationAfterPrint { get; set; }
bool WaitApplicationExitOnPrint { get; set; }
System.IO.FileInfo PdfFile { get; protected set; }
}
internal abstract class ApplicationPrinter : IApplicationPrinter
{
...
}
internal class WordPrinter : ApplicationPrinter
{
internal static string[] PrintableExtensions { get { return new string[]{".doc", ".docx" }; } }
...
}
internal class ExcelPrinter : ApplicationPrinter
{
internal static string[] PrintableExtensions { get { return new string[]{".xls", ".xlsx" }; } }
...
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个Dictionary
可打印的文件扩展名和Type
可以打印此类文件的相应类.我不希望实例在字典中的类.
private static Dictionary<string, Type> FileConverters;
static Printer()
{
FileConverters = new Dictionary<string, Type>();
foreach (string ext in WordPrinter.PrintableExtensions)
{
FileConverters.Add(ext, typeof(WordPrinter));
}
string filename = "textfile.txt";
string extension = filename.Substring(filename.LastIndexOf("."));
if (FileConverters.ContainsKey(extension))
{
IApplicationPrinter printer = ((IApplicationPrinter)FileConverters[extension]).CreateInstance(filename, "Printer");
printer.Print();
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法Dictionary<string, Type> FileConverters
通过将其限制为实现IApplicationPrinter的值来提高类型安全性?换句话说,这样的事情是可能的:
private static Dictionary<string, T> FileConverters where T: IApplicationPrinter;
Run Code Online (Sandbox Code Playgroud)
更新:由于以下两个原因,我不想存储实例:
string[] PrintableExtensions
)字典将扩展名存储为键.在创建和存储同一类的多个分隔实例时没有任何实用工具.我的做法略有不同:
private Dictionary<String, Func<IApplicationPrinter>> _converters;
public void Initialise()
{
foreach (string ext in WordPrinter.PrintableExtensions)
{
_converters.Add(ext, () => new WordPrinter());
}
}
public IApplicationPrinter GetPrinterFor(String extension)
{
if (_converters.ContainsKey(extension)) //case sensitive!
{
return _converters[extension].Invoke();
}
throw new PrinterNotFoundException(extension);
}
Run Code Online (Sandbox Code Playgroud)
此方法不会根据您的需要将实例存储在字典中,并且每次调用时都会为您创建一个新实例GetPrinterFor
。它也具有更强的类型,因为 的返回类型Func<>
必须是IApplicationPrinter
。
不是直接的 - 请记住,您放入字典中的内容是Type
对象,而不是实现IApplicationPrinter
.
这里最好的选择可能是通过检查IApplicationPrinter
是否type.GetInterface("IApplicationPrinter")
返回 null 来检查添加到字典中的每种类型是否实现了。