[英]Implementing a Derived Class of TextWriter
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. 第1类:将
TextWriter
作为构造函数参数并将其用作输出流。
Class 2: Provides a method WriteLine(string)
. 第2类:提供
WriteLine(string)
方法WriteLine(string)
。
I need an adapter, such that all the output of Class1 is written to Class2. 我需要一个适配器,这样Class1的所有输出都写入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. 因此,我启动了一个适配器,它扩展了
TextWriter
并缓冲了传入的文本,并在新行到达时将其刷新到class2实例。
However, there are many and more methods in TextWriter - which should I implement? 但是,TextWriter中有很多方法 - 我应该实现哪些方法? Output in Class1 is string only.
Class1中的输出仅为字符串。
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... 根据MSDN,应该至少覆盖Write(char),但是,这强制我自己完成所有\\ r \\ n新行处理...
Q1: Do you know of a better way to reach my goal? Q1:你知道更好的方法来实现我的目标吗? Q2: If no, which TextWriter methods should I override to have minimum implementation effort.
Q2:如果不是,我应该覆盖哪些TextWriter方法以实现最小的实现工作。
Implementing Write(char)
on your TextWriter
derived class is all you need to do. 您需要在
TextWriter
派生类上实现Write(char)
。 If somebody calls WriteLine
on your new class, the base class WriteLine
method is called. 如果有人在您的新类上调用
WriteLine
,则会调用基类WriteLine
方法。 It will do the right thing: call your Write
method with the individual \\r
and \\n
characters. 它会做正确的事情:使用单独的
\\r
和\\n
字符调用Write
方法。
Actually, WriteLine(string)
looks something like this: 实际上,
WriteLine(string)
看起来像这样:
void WriteLine(string s)
{
Write(s);
Write("\r\n");
}
And Write(string)
is, in effect: 而
Write(string)
实际上是:
foreach (char c in s)
{
Write(c);
}
All of the Write
methods in TextWriter
resolve to something that calls Write(char)
in a loop. TextWriter
所有Write
方法都解析为在循环中调用Write(char)
东西。
You really don't have to implement anything else. 你真的没有必要实现其他任何东西。 Just override
Write(char)
and plug it in. It will work. 只需覆盖
Write(char)
并将其插入即可。它可以正常工作。
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: 这是一个最小的
TextWriter
后代:
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. 根据我的经验,我必须覆盖
WriteLine()
和WriteLine(string)
才能使这些函数正常工作。
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.
顺便说一句,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("&", "&").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(); }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.