Как уже упоминалось в этом ответе, единственный способ правильно обойти это - сделать , как рекомендовано в CA2202 и использовать внешний блок try-finally вместо внешнего блока using,Внутри внутреннего использования установите для внешнего объекта IDisposable значение null, чтобы предотвратить доступ к нему после завершения внутреннего использования.
Вот обобщенная оболочка, которая делает это «правильно», то есть работает с плохо спроектированным XmlReader (может быть, он не должен был вступать во владение потоком, который он получает? Не уверен, каким будет правильный способ сделать это)
Отказ от ответственности : Не проверено
public static TResult SafeNestedUsing<TOuter, TInner, TResult>(Func<TOuter> createOuterDisposable, Func<TOuter, TInner> createInnerDisposable, Func<TInner, TResult> body)
where TInner : IDisposable
where TOuter : class, IDisposable
{
TOuter outer = null;
try
{
outer = createOuterDisposable();
using (var inner = createInnerDisposable(outer))
{
var result = body(inner);
outer = null;
return result;
}
}
finally
{
if (null != outer)
{
outer.Dispose();
}
}
}
Пример использования:
SafeNestedUsing<MemoryStream, XmlReader, XmlDocument>(
() => new MemoryStream(array),
(memStream) => XmlReader.Create(memStream, xmlReaderSettings),
(xmlReader) =>
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);
return xmlDoc;
});
Это довольно довольно неуклюже, и вы можете утверждать, что вместо этого лучше повторить попытку try / set null / finally.Но для повторяющегося паттерна вложенных использований я бы предпочел сделать это таким образом, чем повторять все это каждый раз.