具有私有派生类的抽象类:一些实现方法

时间:2015-12-11 11:05:34

标签: c# inheritance

我创建了一个类来生成2个类似但非常不同的报告。为此我使用了我在这里找到的模式:https://stackoverflow.com/a/29907649/3410196 它使用一个抽象基类,它包含带有公共构造函数的私有派生类,因此其他代码实际上永远不能访问派生类的构造函数,只能使用static Create()方法创建对象。

现在我遇到了一个问题: 一切正常,我可以导出报告等。但现在我必须能够以不同的格式导出一个的报告。有没有什么办法可以通过基类只为那个派生类访问这个方法?否则我将throw new NotImplementedException()或强迫我的用户使用以下内容:

//Is actually multiReport (multireport:report)
Report report = Report.Create(...);
MemoryStream stream = (report as multireport).ExportOtherFormat();

我怀疑这是可能的,但也许有办法!

3 个答案:

答案 0 :(得分:1)

您不能使其中一个子类的方法对外部用户可见,因为它们创建了基类的实例(即basereport,而不是multireport)。除非他们知道他们正在查看ExportOtherFormat的实例,而不是multireport,否则他们无法致电basereport

解决此问题的一种方法是隐藏用户的格式决策。制作enum格式,并制作获取它的ExportWithFormat方法:

[Flags]
enum ReportFormat {
    Simple    = 1
,   Extended  = 2
,   Special   = 4
,   Multifile = 8
}

将这些属性和方法添加到基类:

public ReportFormat AvailableExportFormats { get {... } }

public MemoryStream ExportWithFormat(ReportFormat format);

现在,您的Multireport可以返回AvailableExportFormats中支持的额外格式的特殊标志,并在ExportWithFormat方法中将该标志传回给它时生成正确的导出。

答案 1 :(得分:0)

如果我理解正确,你需要这样的东西,以便ReportB将提供Export方法的新实现:

abstract class Report
{
    private Report() {}

    public virtual MemoryStream Export() { ... }  

    private class ReportA : Report
    {
        public ReportA() { ... }
    }

    private class ReportB : Report
    {
        public ReportB() { ... }
        new public virtual MemoryStream Export() { ... }
    }

    public static Report Create() { ... }
}

答案 2 :(得分:0)

毕竟我找到了一个解决方案(可能不是最好的)来使其中一个类公开并公开这样的方法,但没有在其他子类上使用它:

abstract class Report
{
private Report() {}

public abstract MemoryStream ExportPDF() { ... }  

public class ReportA : Report
{
    public ReportA() { ... }
    public override MemoryStream ExportPDF() {...}
    public MemoryStream ExportCSV() {...}
}

private class ReportB : Report
{
    public ReportB() { ... }
    public override MemoryStream ExportPDF() {...}
}

public static Report Create() { ... }
}

现在只有子类A具有方法ExportCSV()并显示它。现在人们可以打电话给构造函数来制作一个sublcass A然而,我并不是很喜欢