In C#, why can't I pass a StringReader to a method with a Stream parameter?
In .net 4 and C#. I've implemented a static method to deserialize an XML stream into an object. This is only one xml format going into one object, so I'm not trying to do anything fancy with that. Since I can get this XML content in a variety of ways, I thought I'd make the parameter passed to the static method a Stream object. I'd thought that it would then take any object derived from base class Stream -- like FileStream, MemoryStream, StringReader, etc.
It works fine when I pass it a FileStream object, but not when I pass it a StringReader.
My static method:
public static MatchObj DeserializeMatch(Stream srXml)
{
XmlSerializer xs = new XmlSerializer(typeof(MatchObj));
MatchObj mObj = (MatchObj)xs.Deserialize(srXml);
return mObj;
}
It works with a FileStream:
MatchObj objReply;
using (FileStream fs = new FileStream(Server.MapPath("/App_Data/Match.xml"), FileMode.Open))
{
objReply = MSt开发者_StackOverflow社区atic.DeserializeMatch(fs);
fs.Close();
}
But not a StringReader:
StringReader sr = new StringReader(Request.Form["mXML"]);
MatchObj objReply = MStatic.DeserializeMatch(sr);
The build error is: "cannot convert from 'System.IO.StringReader' to 'System.IO.Stream'"
Which in and of itself makes sense, but I thought that since StringReader implements TextReader, that it counted as Stream? XML Deserializer works fine with either.
I've worked around it simply by overloading that method to take a StringReader, but I hate to see what I thought was an elegant idea fall apart. Any ideas on why this doesn't work, and/or a way to make it work?
Here is the inheritance hierarchy of a StringReader...
System.Object System.MarshalByRefObject System.IO.TextReader System.IO.StringReader
I would suggest putting Request.Form["mXML"] into a MemoryStream instead.
This might work (untested)...
var xmlBytes = Encoding.UTF8.GetBytes(Request.Form["mXML"]);
var ms = new MemoryStream(xmlBytes);
var reply = MStatic.DeserializeMatch(ms);
Well, technically, (but obviously) Because neither StringReader
nor TextReader
derive from Stream
.
Perhaps more informatively, a Stream
is the abstract base class that represents a sequence of Bytes. All the [Something]Reader
and [Something]Writer
classes are designed to read or write to/from a Stream
, they are not themselves Stream
objects. It is arguably true, however that these classes are all very poorly named and contribute to the misunderstanding that many developers have about this entire topic.
TextReader isn't a stream either, it inherits directly from MarshalByRefObject: http://msdn.microsoft.com/en-us/library/system.io.textreader.aspx
精彩评论