简体   繁体   English

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

[英]Abstract class with private derived classes: implement method for some

I made a class to generate 2 similar but yet very different reports. 我制作了一个类来生成2个相似但又非常不同的报告。 For that I used the pattern I found here: https://stackoverflow.com/a/29907649/3410196 It uses an abstract baseclass, which contains private derived classes with public constructors, so other code can never actually access the constructors of the derived class, and only create objects by using the static Create() method. 为此,我使用了在这里找到的模式: https : //stackoverflow.com/a/29907649/3410196它使用了一个抽象基类,该基类包含具有公共构造函数的私有派生类,因此其他代码永远无法实际访问派生类的构造函数类,并且只能使用static Create()方法创建对象。

Now I'm facing a problem: Everything works fine and I can export the reports etc. But now I have to be able to export one of the reports in a different format. 现在,我面临一个问题:一切正常,可以导出报告等。但是现在,我必须能够以其他格式导出其中一个报告。 Is there any way I can make this method accessible through the base class only for that one derived class? 有什么方法可以使该方法只能通过一个派生类通过基类访问? Otherwise I'll have to throw new NotImplementedException() or force my users to use something like this: 否则,我将不得不throw new NotImplementedException()或强制我的用户使用以下内容:

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

I doubt this is possible but maybe there is a way! 我怀疑这是可能的,但也许有办法!

You cannot make a method of one of the subclasses visible to outside users, because they create an instance of the base class (ie basereport , not multireport ). 你不能让外部用户可见的一个子类的方法,因为他们创造的基类的一个实例(即basereport ,没有multireport )。 They wouldn't be able to call ExportOtherFormat unless they know that they are looking at an instance of multireport , not basereport . 他们将无法调用ExportOtherFormat ,除非他们知道他们正在寻找的一个实例multireport ,不basereport

One way to work around this issue is to hide the format decision from the users as well. 解决此问题的一种方法是也向用户隐藏格式决定。 Make an enum of formats, and make ExportWithFormat method that takes it: 进行格式enum ,并制作采用该格式的ExportWithFormat方法:

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

Add these properties and methods to the base class: 将这些属性和方法添加到基类中:

public ReportFormat AvailableExportFormats { get {... } }

public MemoryStream ExportWithFormat(ReportFormat format);

Now your Multireport can return the special flag for the extra format that it supports in AvailableExportFormats , and produce the proper export when that flag is passed back to it in ExportWithFormat method. 现在,您的Multireport可以为AvailableExportFormats支持的额外格式返回特殊标志,并在ExportWithFormat方法中将该标志传递回该标志时产生适当的导出。

If I understood you correctly, you need something like that, so that ReportB will provide new implementation of Export method: 如果我对您的理解正确,则需要类似的内容,以便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() { ... }
}

After all I went for a solution (maybe not the best) to make one of the classes public and expose the method like that, but not have it on the other subclasses: 毕竟,我寻求一个解决方案(也许不是最好的)来公开一个类,并公开这样的方法,但在其他子类上却没有:

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() { ... }
}

Now only subclass A has the method ExportCSV() and shows it. 现在只有子类A具有方法ExportCSV()并显示它。 Now people can call the constructor to make a sublcass A however, which I don't really like 现在,人们可以调用构造函数来制作sublcass A了,但是我不是很喜欢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Derived类中的抽象方法覆盖,如何使私有 - abstract method override in Derived class, how to make private Array中抽象类的派生类 - Derived classes of abstract class in an Array 是否可以(部分)实现抽象方法,并且仍然需要派生类也可以实现它? - Is it possible to (partially) implement an abstract method and still require derived classes to also implement it? 摘要派生类没有抽象方法实现 - Abstract Derived class without abstract method implementation 如何强制所有派生类实现抽象方法或属性? - How can I force all derived classes to implement an abstract method or property? 如何为c#中的泛型派生类实现抽象非泛型基类? - How to implement a abstract nongeneric base class, for generic derived classes in c#? XmlSerializer +抽象类+派生类=无用的命名空间 - XmlSerializer + Abstract class + Derived classes = Useless namespaces 一个抽象类,可以由数据库类派生 - An abstract class which can be derived by database classes 努力在派生类中实现抽象属性 - Struggling to implement abstract property in derived class 在抽象基类的静态方法中实例化几个派生类中的任何一个(取决于参数) - Instantiate any one of several derived classes (depending on an argument) within a static method of the abstract base class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM