Readonly StringWriter.Encoding: should I care?
During code review we spotted a class inherited from StringWriter
. The only intention of that
was the need to override StringWriter.Encoding
property that was read-only for some reason.
The use case was the XML serialization.
The code was like that (of course it was googled :) )
The idea to inherit from BCL class always looks weird to me. Especially in this case. The first question:
why default StringWriter.Encoding
doesn’t work? And next one: why is it read-only?
It turned out that Encoding
affects the encoding
value of XML declaration. This code produces following:
While standard StringWriter
generates
OK, but why is it read-only? To figure it out I opened source code
of StringWriter
. And figured out the following:
- It wraps a static private
field that is essentially the
Encoding.Unicode
, that in turn is an UTF-16 encoding - It is not used in the class itself
Seems like it is a completely useless thing. And StringWriter
itself is just a wrapper around
StringBuilder
that have no concept of encoding at all. As we might remember, internally .NET strings
use UTF-16. And that Encoding is exactly what
is returned by StringWriter.Encoding
. That is why it cannot (and should not) be changed – because we
cannot change internal encoding of string
.
The fact that XmlTextWriter
uses that property to render encoding in declaration seem to be OK, but this
particular usage is not. StringWriterWithEncoding
just fools it’s clients advertising different encoding.
Total hack.
But how to do it properly? In fact we don’t need StringWriter
at all. Curious reader can notice that the code
from the top just uses StringWriter
to get a string and immediately after that takes bytes from that string to
MemoryStream
. Why not use stream instead?