簡體   English   中英

實現派生類的TextWriter

[英]Implementing a Derived Class of TextWriter

我有兩個課程,我不能以任何方式改變:

第1類:將TextWriter作為構造函數參數並將其用作輸出流。

第2類:提供WriteLine(string)方法WriteLine(string)

我需要一個適配器,這樣Class1的所有輸出都寫入Class2。 因此,我啟動了一個適配器,它擴展了TextWriter並緩沖了傳入的文本,並在新行到達時將其刷新到class2實例。

但是,TextWriter中有很多方法 - 我應該實現哪些方法? Class1中的輸出僅為字符串。

根據MSDN,應該至少覆蓋Write(char),但是,這強制我自己完成所有\\ r \\ n新行處理...

Q1:你知道更好的方法來實現我的目標嗎? Q2:如果不是,我應該覆蓋哪些TextWriter方法以實現最小的實現工作。

您需要在TextWriter派生類上實現Write(char) 如果有人在您的新類上調用WriteLine ,則會調用基類WriteLine方法。 它會做正確的事情:使用單獨的\\r\\n字符調用Write方法。

實際上, WriteLine(string)看起來像這樣:

void WriteLine(string s)
{
    Write(s);
    Write("\r\n");
}

Write(string)實際上是:

foreach (char c in s)
{
    Write(c);
}

TextWriter所有Write方法都解析為在循環中調用Write(char)東西。

你真的沒有必要實現其他任何東西。 只需覆蓋Write(char)並將其插入即可。它可以正常工作。

可以覆蓋其他方法。 這樣做會使您的課程更有效(更快)。 但這不是必需的。 我說你做的最簡單的事情。 然后,如果您在分析自定義編寫器太慢后確定,請根據需要覆蓋其他方法。

這是一個最小的TextWriter后代:

public class ConsoleTextWriter: TextWriter
{
    public override void Write(char value)
    {
        Console.Write(value);
    }

    public override Encoding Encoding
    {
        get { return Encoding.Default; }
    }
}

如果我然后寫:

using (var myWriter = new ConsoleTextWriter())
{
    myWriter.Write("hello, world");
    myWriter.WriteLine();
    myWriter.WriteLine();
    myWriter.WriteLine("Goodbye cruel world.");
    myWriter.Write("Fee fie foe foo!");
}

輸出是:

hello, world

Goodbye cruel world.
Fee fie foe foo!

我正在添加另一個答案,因為我無法得到上述答案!

根據我的經驗,我必須覆蓋WriteLine()WriteLine(string)才能使這些函數正常工作。

這是一個可用於在長時間運行的任務中編寫網頁的示例。 順便說一句,HttpResponse對象來自ASP.net MVC。

public class WebConsoleWriter : TextWriter
{
    HttpResponseBase Response { get; set; }
    bool FlushAfterEveryWrite { get; set; }
    bool AutoScrollToBottom { get; set; }
    Color BackgroundColor { get; set; }
    Color TextColor { get; set; }

    public WebConsoleWriter(HttpResponseBase response, bool flushAfterEveryWrite, bool autoScrollToBottom)
    {
        Response = response;
        FlushAfterEveryWrite = flushAfterEveryWrite;
        AutoScrollToBottom = autoScrollToBottom;
        BackgroundColor = Color.White;
        TextColor = Color.Black;
    }

    public WebConsoleWriter(HttpResponseBase response, bool flushAfterEveryWrite,  bool autoScrollToBottom, Color backgroundColor, Color textColor)
    {
        Response = response;
        FlushAfterEveryWrite = flushAfterEveryWrite;
        AutoScrollToBottom = autoScrollToBottom;
        BackgroundColor = backgroundColor;
        TextColor = textColor;
    }

    public virtual void WritePageBeforeStreamingText()
    {
        string headerFormat =
@"<!DOCTYPE html>
<html>
<head>
    <title>Web Console</title>
    <style>
        html {{
            background-color: {0};
            color: {1};
        }}
    </style>        
</head>
<body><pre>";
        string backgroundColorHex = ColorTranslator.ToHtml(BackgroundColor);
        string foregroundColorHex = ColorTranslator.ToHtml(TextColor);
        Response.Write(string.Format(headerFormat, backgroundColorHex, foregroundColorHex));

        // Add a 256 byte comment because I read that some browsers will automatically buffer the first 256 bytes.
        Response.Write("<!--");
        Response.Write(new string('*', 256));
        Response.Write("-->");
        Response.Flush();
    }

    public virtual void WritePageAfterStreamingText()
    {
        Response.Write("</pre></body></html>");
    }

    public override void Write(string value)
    {
        string encoded = Encode(value);
        Response.Write(encoded);            
        if (FlushAfterEveryWrite)
            Response.Flush();
    }

    public override void WriteLine(string value)
    {
        Response.Write(Encode(value) + "\n");
        if (AutoScrollToBottom)
            ScrollToBottom();
        if (FlushAfterEveryWrite)
            Response.Flush();
    }

    public override void WriteLine()
    {
        Response.Write('\n');
        if (AutoScrollToBottom)
            ScrollToBottom();
        if (FlushAfterEveryWrite)
            Response.Flush();
    }

    private string Encode(string s)
    {
        return s.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
    }

    public override void Flush()
    {
        Response.Flush();
    }

    public void ScrollToBottom()
    {
        Response.Write("<script>window.scrollTo(0, document.body.scrollHeight);</script>");
    }

    public override System.Text.Encoding Encoding
    {
        get { throw new NotImplementedException(); }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM