using(IDisposable obj = new …) в C# для записи блоков кода в потоке (например, XML)

Я начал использовать классы, реализующие IDisposable, для записи блоков в потоки с оператором using. Это полезно для сохранения правильного размещения и предотвращения отсутствия или неправильного размещения начальных/конечных частей.

По сути, конструктор записывает начало блока (например, открывающий XML-тег), Dispose() — конец (например, закрывающий XML-тег). Примером является UsableXmlElement ниже (он предназначен для больших XML-файлов, поэтому LINQ to XML или XmlDocument в памяти не являются вариантами).

Однако эти IDisposable не реализуют сложный шаблон, рекомендованный Microsoft, с деструктором/финализатором, отдельным методом Dispose(bool) и GC.SuppressFinalize(). Dispose просто записывает конечный элемент, и все.

Есть ли в этом какая-то обратная сторона или это хороший способ поддерживать правильное вложение элементов?

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();
    }
}

Использование выглядит следующим образом:

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
   }
}

Результат:

<RootElement DocVersion="123">
    <InnerElement>
       <!-- anything -->
    </InnerElement>
</RootElement>
7
задан Ben Voigt 26 March 2012 в 20:57
поделиться