【问题标题】:In C#, why can't I pass a StringReader to a method with a Stream parameter?在 C# 中,为什么我不能将 StringReader 传递给带有 Stream 参数的方法?
【发布时间】:2010-12-08 02:19:10
【问题描述】:

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

当我向它传递一个 FileStream 对象时它工作正常,但当我向它传递一个 StringReader 时它就不行了。

我的静态方法:

    public static MatchObj DeserializeMatch(Stream srXml)
    {
        XmlSerializer xs = new XmlSerializer(typeof(MatchObj));
        MatchObj mObj = (MatchObj)xs.Deserialize(srXml);

        return mObj;
    }

它适用于 FileStream:

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

            fs.Close();
        }

但不是 StringReader:

StringReader sr = new StringReader(Request.Form["mXML"]);
MatchObj objReply = MStatic.DeserializeMatch(sr);

构建错误是:“无法从 'System.IO.StringReader' 转换为 'System.IO.Stream'”

这本身是有道理的,但我认为既然 StringReader 实现了 TextReader,它算作 Stream? XML Deserializer 两者都可以正常工作。

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

【问题讨论】:

  • 这对我来说可能听起来很无聊......但你确定 StringReader 继承自任何类型的 Stream 吗?

标签: c# .net xml


【解决方案1】:

这里是 StringReader 的继承层次...

系统对象 System.MarshalByRefObject System.IO.TextReader System.IO.StringReader

我建议将 Request.Form["mXML"] 改为 MemoryStream。

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

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

【讨论】:

  • +1。我建议var ms = new MemoryStream(Encoding.UTF8.GetBytes(sr.ReadToEnd())); 或使用var ms = new MemoryStream(Encoding.UTF8.GetBytes(Request.Form["mXML"])); 一起跳过字符串阅读器
  • 我想我一直认为 TextReader 从 Stream 继承而来。让我坚持这一点的一件事是 XmlSerializer.Deserializer 两者都可以正常工作。我后来发现那个方法只是重载了,除了 Stream,还可以使用 TextReader 或 XmlReader。
  • @Ani -- 尝试了你的建议,它奏效了!我做了:MatchObj objReply = MStatic.DeserializeMatch(new MemoryStream(Encoding.UTF8.GetBytes(Request.Form["mXML"])));
【解决方案2】:

好吧,从技术上讲,(但显然)因为StringReaderTextReader 都不是从Stream 派生的。
也许更多信息,Stream 是代表字节序列的抽象基类。所有[Something]Reader[Something]Writer 类都设计为读取写入 到/从@987654327 @,它们本身不是Stream 对象。可以说是真的,但是这些类的名称都很糟糕,并导致许多开发人员对整个主题产生误解。

【讨论】:

  • 我认为你是对的。对我来说,可以读取或写入流的东西会实现 Stream 基类,这对我来说很直观。但是,我猜不是!
【解决方案3】:

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

【讨论】:

  • 它不是来自 Stream。
  • OP 断言“这本身是有道理的,但我认为由于 StringReader 实现了 TextReader,所以它算作 Stream?”
  • +1:一针见血:TextReader 也不起作用,因此 OP 的假设是无效的。
猜你喜欢
  • 1970-01-01
  • 2020-08-28
  • 2017-06-25
  • 1970-01-01
  • 2018-09-03
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多