C# 如何确定使用哪个抽象类实现?

C# 如何确定使用哪个抽象类实现?,c#,inheritance,abstract-class,C#,Inheritance,Abstract Class,根据某个变量或定义特性,确定要调用哪个抽象类实现的最佳方法是什么 代码示例: public abstract class FileProcesser { private string _filePath; protected FileProcessor(string filePath) { if (filePath == null) { throw new ArgumentNullException("filePa

根据某个变量或定义特性,确定要调用哪个抽象类实现的最佳方法是什么

代码示例:

public abstract class FileProcesser
{
    private string _filePath;

    protected FileProcessor(string filePath)
    {
        if (filePath == null)
        {
            throw new ArgumentNullException("filePath");
        }

        // etc etc

        _filePath = filePath;
    }

    // some example methods for this file
    public abstract int GetFileDataCount();
    public abstract IEnumerable<FileItem> GetFileDataItems();
}

// specific implementation for say, a PDF type of file
public class PdfFileProcesser : FileProcessor
{
    public PdfFileProcessor(string filePath) : base(filePath) {}

    // implemented methods
}

// specific implementation for a type HTML file
public class HtmlFileProcessor : FileProcessor
{
    public HtmlFileProcessor(string filePath) : base(filePath) {}

    // implemented methods 
}

public class ProcessMyStuff()
{
    public void RunMe()
    {
        // the code retrieves the file (example dummy code for concept)
        List<string> myFiles = GetFilePaths();

        foreach (var file in myFiles)
        {
            if (Path.GetExtension(file) == ".pdf")
            {
                FileProcessor proc = new PdfFileProcessor(file);
                // do stuff
            }
            else if (Path.GetExtension(file) == ".html")
            {
                FileProcessor proc = new HtmlFileProcessor(file);
                // do stuff
            }
            // and so on for any types of files I may have
            else 
            { 
                // error
            }
        }
    }
}
公共抽象类文件处理器
{
私有字符串\u文件路径;
受保护的文件处理器(字符串文件路径)
{
if(filePath==null)
{
抛出新的ArgumentNullException(“文件路径”);
}
//等等
_filePath=filePath;
}
//此文件的一些示例方法
公共抽象int GetFileDataCount();
公共抽象IEnumerable GetFileDataItems();
}
//例如,PDF文件类型的具体实现
公共类PdfileProcessor:FileProcessor
{
公共PdfileProcessor(字符串文件路径):基本(文件路径){}
//实施方法
}
//类型HTML文件的特定实现
公共类HtmlFileProcessor:FileProcessor
{
公共HtmlFileProcessor(字符串文件路径):基(文件路径){}
//实施方法
}
公共类ProcessMyStuff()
{
public void RunMe()
{
//代码检索文件(概念的示例伪代码)
List myFiles=getfilepath();
foreach(myFiles中的var文件)
{
if(Path.GetExtension(file)=“.pdf”)
{
FileProcessor proc=新的PdfFileProcessor(文件);
//做事
}
else if(Path.GetExtension(文件)=“.html”)
{
FileProcessor proc=新的HtmlFileProcessor(文件);
//做事
}
//等等我可能有的任何类型的文件
其他的
{ 
//错误
}
}
}
}

我觉得通过使用更好的OO概念,似乎有一种“更聪明”的方法来做到这一点。我写的代码是一个示例,演示了我试图理解的内容,如果有简单的错误,很抱歉,但基本思想就在那里。我知道这是一个具体的例子,但我认为这也适用于许多其他类型的问题

我建议使用工厂检索处理器:

    foreach (var file in myFiles)
    {
        string extension = Path.GetExtension(file);
        IFileProcessor proc = FileProcessorFactory.Create(extension);
        // do stuff
    }
那么你的工厂是这样的:

public static class FileProcessorFactory 
{
    public static IFileProcessor Create(string extension) {
        switch (extension) {
            case "pdf":
                return new PdfFileProcessor();
            case "html":
                return new HtmlFileProcessor();
            // etc...
        }
    }
}

请注意,我们使用的是一个接口,您的抽象类将从该接口继承。这允许返回任何继承类型。

查看“抽象工厂模式”。这几乎是工厂的基本情况。您似乎正在实施战略模式。我更倾向于创建一个包含IProcessFiles接口的处理器类,该接口定义了所涉及的基本方法,并分别为每种类型运行处理器,每个处理器只查找它们可以处理的文件类型。它可能效率较低,但更干净。公平地说,这只是移动了if链,无法很好地适应其他策略。在添加新的
案例后,任何新的文件处理器都需要与工厂重新编译程序集。我同意mayabelle的观点。如果在库A和库B中有处理器和工厂方法,请添加新的处理器,然后让B有自己的工厂方法调用A,如果在A中找不到任何内容,则在自己的处理器上回退。或者,您可以将属性及其扩展放在处理器类上,并使用反射选择正确的一个。。。但坦率地说,我怀疑这是否值得。或者您可以将以前的if转换为全局字典。。。但有时,一个好的老人如果不是那么坏。