1

我有一个简单的类 XMLSTream,它允许我将数据从应用程序传递到在 Word 中打开的 XML 文档。

我有一个简单的 HTMLStream 类,它允许我将数据从应用程序传递到在 Internet Explorer 中打开的 HTML 文档。

我的两个流类都可以完美地单独工作。

我已将这些类与匹配结构对齐,希望用户从文件对话框中选择将确定使用哪个“流类”。我无法弄清楚的是如何在调用类中使用相同的代码,而不管类型如何。

myHtmlStream
{
protected Stream myStream;
protected StreamWriter myWriter;
Open() {// block of code};
Close() {// block of code} ;
WriteLine (string myLine) { // block of code} ; 
// etc;  
}

myXMLStream
{
protected Stream myStream;
protected StreamWriter myWriter;
Open() {// block of code};
Close() {// block of code} ;
WriteLine (string myLine) { // block of code} ; 
// etc;  
}

调用类执行以下操作:

SaveFileDialog sDlg = new SaveFileDialog();
sDlg.Filter = "htm files (*.htm)|*.htm|xml files (*.xml)|*.xml";
sDlg.FilterIndex = 1;
if (sDlg.ShowDialog() == DialogResult.OK)
{
    if (sDlg.FilterIndex == 1)
    {
        myHtmlStream mH = new myHtmlStream();
        mH.Open();
        mH.WriteLine("This is a HTML document");
        mH.Close();
    }
    else if (sDlg.FilterIndex == 2)
    {
        myXMLStreammX mX= new myXMLStream();
        mX.Open();
        mX.WriteLine("This is an XML document");
        mX.Close();
    }

}

您可以看到无论选择何种文件类型都调用了相同的步骤,但是将组件添加到报告中很麻烦,因为它们必须输入两次。(我也有为复杂报告创建表格、填充单元格等的方法。)。

通过继承,我应该能够简化这一点,任何人都可以链接到任何可能有助于帮助的东西?在实际代码中,它以超过 4 行的 XML/HTML 输出方式输出实际数据。我知道理论上至少有一种优雅的方式来处理这个

4

1 回答 1

2

In my opinion, the best solution here is to define an interface and an abstract class.

Define something along the lines of this:

public interface IOutputStream
{
    void Open();
    void Close();
    void WriteLine(string line);
}

public abstract class OutputStreamBase : IOutputStream
{
    // create cross-cutting concerns here, logging, file handling, etc.
    // create virtual methods and properties that are common to all descendants
    public virtual void Open()
    {
        throw new System.NotImplementedException();
    }

    public virtual void Close()
    {
        throw new System.NotImplementedException();
    }

    public virtual void WriteLine(string line)
    {
        throw new System.NotImplementedException();
    }

    protected virtual void DoSomething()
    {
    }

    protected abstract void DoSomethingElse();
}

Then, once you have these, you can define as many concrete implementations as you need:

public class HtmlStream : OutputStreamBase
{
    protected override void DoSomethingElse()
    {
        throw new System.NotImplementedException();
    }
}

public class XmlStream : OutputStreamBase
{
    protected override void DoSomethingElse()
    {
        throw new System.NotImplementedException();
    }
}

Then, in your calling code, create a variable of type IOutputStream and assign it as needed:

    public void Test()
    {
        IOutputStream outputStream;

        if (sDlg.ShowDialog() == DialogResult.OK)
        {
            if (sDlg.FilterIndex == 1)
                outputStream = new HtmlStream();
            else if (sDlg.FilterIndex == 2)
                outputStream = new XmlStream();
            else
                throw new InvalidOperationException();
        }

        outputStream.Open();
        outputStream.WriteLine("ContentHere");
        outputStream.Close();
    }
}

Then, you can use the same method calls regardless of implementation.

Since you are dealing with resources such as files, streams, etc. it might also be prudent to implement the IDisposable interface too, and wrap the whole thing up in a (using var stream = ... ) block to ensure your resources get flushed, closed and disposed of when finished.

于 2013-10-30T00:44:57.490 回答