I have two classes, none of which I can change in any way:
Class 1: Takes a TextWriter
as constructor parameter and uses it as an output stream.
Class 2: Provides a method WriteLine(string)
.
I need an adapter, such that all the output of Class1 is written to Class2. Therefore I started an adapter which extends TextWriter
and buffers incoming text, flushing it to the class2 instance as soon as a new line arrives.
However, there are many and more methods in TextWriter - which should I implement? Output in Class1 is string only.
According to MSDN one should override Write(char) as a minimum, however, this enforces me to do all the \r\n new line handling myself as well...
Q1: Do you know of a better way to reach my goal? Q2: If no, which TextWriter methods should I override to have minimum implementation effort.
Implementing Write(char)
on your TextWriter
derived class is all you need to do. If somebody calls WriteLine
on your new class, the base class WriteLine
method is called. It will do the right thing: call your Write
method with the individual \r
and \n
characters.
Actually, WriteLine(string)
looks something like this:
void WriteLine(string s) { Write(s); Write("\r\n"); }
And Write(string)
is, in effect:
foreach (char c in s) { Write(c); }
All of the Write
methods in TextWriter
resolve to something that calls Write(char)
in a loop.
You really don't have to implement anything else. Just override Write(char)
and plug it in. It will work.
You can override those other methods. Doing so will make your class a little more efficient (faster). But it's not required. I say do the simplest thing you can. Then, if you determine after profiling that your custom writer is too slow, override other methods as necessary.
Here's a minimal TextWriter
descendant:
public class ConsoleTextWriter: TextWriter { public override void Write(char value) { Console.Write(value); } public override Encoding Encoding { get { return Encoding.Default; } } }
If I then write:
using (var myWriter = new ConsoleTextWriter()) { myWriter.Write("hello, world"); myWriter.WriteLine(); myWriter.WriteLine(); myWriter.WriteLine("Goodbye cruel world."); myWriter.Write("Fee fie foe foo!"); }
The output is:
hello, world Goodbye cruel world. Fee fie foe foo!
I'm adding another answer because I couldn't get the above answer to work!
In my experience, I must override WriteLine()
and WriteLine(string)
in order for those functions to work.
Here's an example that can be used to write a web page as a long-running task goes on. BTW, the HttpResponse object is from 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("&", "&").Replace("<", "<").Replace(">", ">"); } 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(); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With