在C#中,为什么我不能将StringReader传递给带有Stream参数的方法?

时间:2021-08-19 03:09:17

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.

在.net 4和C#中。我已经实现了一个静态方法来将XML流反序列化为对象。这只是一个xml格式进入一个对象,所以我不想做任何花哨的事情。由于我可以通过各种方式获取此XML内容,因此我认为我将传递给静态方法的参数作为Stream对象。我认为它会接受从基类Stream派生的任何对象 - 如FileStream,MemoryStream,StringReader等。

It works fine when I pass it a FileStream object, but not when I pass it a StringReader.

当我传递一个FileStream对象时它工作正常,但是当我传递一个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:

它适用于FileStream:

        MatchObj objReply;
        using (FileStream fs = new FileStream(Server.MapPath("/App_Data/Match.xml"), FileMode.Open))
        { 
            objReply = MStatic.DeserializeMatch(fs);

            fs.Close();
        }

But not a StringReader:

但不是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'"

构建错误是:“无法从'System.IO.StringReader'转换为'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.

哪个本身有意义,但我认为既然StringReader实现了TextReader,它算作Stream? XML Deserializer可以正常工作。

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?

我只是通过重载该方法来使用StringReader来解决它,但我讨厌看到我认为是一个优雅的想法分崩离析。关于为什么这不起作用的任何想法,和/或使其有效的方法?

3 个解决方案

#1


7  

Here is the inheritance hierarchy of a StringReader...

这是StringReader的继承层次结构......

System.Object 
  System.MarshalByRefObject
    System.IO.TextReader
      System.IO.StringReader

I would suggest putting Request.Form["mXML"] into a MemoryStream instead.

我建议将Request.Form [“mXML”]放入MemoryStream中。

This might work (untested)...

这可能有用(未经测试)......

var xmlBytes = Encoding.UTF8.GetBytes(Request.Form["mXML"]);
var ms = new MemoryStream(xmlBytes);
var reply = MStatic.DeserializeMatch(ms);

#2


4  

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.

从技术上讲,(但很明显)因为StringReader和TextReader都不是从Stream派生的。也许更具信息性,Stream是表示字节序列的抽象基类。所有[Something] Reader和[Something] Writer类都设计用于读取或写入Stream,它们本身不是Stream对象。可以说这是真的,但是这些类的命名都很差,并且导致许多开发人员对整个主题的误解。

#3


1  

TextReader isn't a stream either, it inherits directly from MarshalByRefObject: http://msdn.microsoft.com/en-us/library/system.io.textreader.aspx

TextReader也不是一个流,它直接从MarshalByRefObject继承:http://msdn.microsoft.com/en-us/library/system.io.textreader.aspx

#1


7  

Here is the inheritance hierarchy of a StringReader...

这是StringReader的继承层次结构......

System.Object 
  System.MarshalByRefObject
    System.IO.TextReader
      System.IO.StringReader

I would suggest putting Request.Form["mXML"] into a MemoryStream instead.

我建议将Request.Form [“mXML”]放入MemoryStream中。

This might work (untested)...

这可能有用(未经测试)......

var xmlBytes = Encoding.UTF8.GetBytes(Request.Form["mXML"]);
var ms = new MemoryStream(xmlBytes);
var reply = MStatic.DeserializeMatch(ms);

#2


4  

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.

从技术上讲,(但很明显)因为StringReader和TextReader都不是从Stream派生的。也许更具信息性,Stream是表示字节序列的抽象基类。所有[Something] Reader和[Something] Writer类都设计用于读取或写入Stream,它们本身不是Stream对象。可以说这是真的,但是这些类的命名都很差,并且导致许多开发人员对整个主题的误解。

#3


1  

TextReader isn't a stream either, it inherits directly from MarshalByRefObject: http://msdn.microsoft.com/en-us/library/system.io.textreader.aspx

TextReader也不是一个流,它直接从MarshalByRefObject继承:http://msdn.microsoft.com/en-us/library/system.io.textreader.aspx