在C#中使用(IDisposable obj = new ...)来编写流中的代码块(例如XML)

Eri*_*art 7 c# xml idisposable using-statement stream

我已经开始使用实现IDisposable的类来使用using语句在流中编写块.这有助于保持正确的嵌套并避免丢失或错误放置的开始/结束部件.

基本上,构造函数编写块的开头(例如打开XML标记),Dispose()结束(例如关闭XML标记).示例是下面的UsableXmlElement(它适用于大型XML,因此内存中的LINQ to XML或XmlDocument不是选项).

但是,这些IDisposable不实现Microsoft推荐的复杂模式,使用Destructor/Finalizer,单独的Dispose(bool)方法和GC.SuppressFinalize().Dispose只是简单地写出end元素,就是这样.

这有什么不妥的,或者这是保持元素正确嵌套的好方法吗?

class UsableXmlElement : IDisposable
{
    private XmlWriter _xwriter;

    public UsableXmlElement(string name, XmlWriter xmlWriter)
    {
        _xwriter = xmlWriter;
        _xwriter.WriteStartElement(name);
    }

    public void WriteAttribute<T>(string name, T value)
    {
        _xwriter.WriteStartAttribute(name);
        _xwriter.WriteValue(value);
        _xwriter.WriteEndAttribute();
    }

    public void WriteValue<T>(T value)
    {
        _xwriter.WriteValue(value);
    }

    public void Dispose()
    {
        _xwriter.WriteEndElement();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法是这样的:

var xWriter = new XmlWriter(...)

using(var rootElement = new UsableXmlElement("RootElement", xWriter)
{
   rootElement.WriteAttribute("DocVersion", 123)
   using(var innerElement = new UsableXmlElement("InnerElement", xwriter)
   {
       // write anything inside Inner element
   }
}
Run Code Online (Sandbox Code Playgroud)

导致:

<RootElement DocVersion="123">
    <InnerElement>
       <!-- anything -->
    </InnerElement>
</RootElement>
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 2

这有什么不好的地方吗

不。无论如何,应该避免使用析构函数(终结器),即使具有资源的类通常可以在没有资源的情况下做得(更好)。

或者这是保持元素正确嵌套的好方法?

是的。您可以System.Web.Mvc.Html.MvcForm作为参考。

这些 IDisposable 没有实现 Microsoft 推荐的复杂模式

这种“完整”模式是正确的,但已经过时了。它仅描述“裸”非托管资源的情况。不幸的是,没有提供仅处理托管资源的官方参考。