[英]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.