Он может это сделать, если вы неявно или явно устанавливаете выравнивание структуры. Строка, которая выровнена 4, всегда будет кратной 4 байтам, даже если размер ее членов будет чем-то, что не кратно 4 байтам.
Также библиотека может быть скомпилирована под x86 с 32- бит, и вы можете сравнить его компоненты с 64-битным процессом, это даст вам другой результат, если вы делаете это вручную.
Вы можете просто сделать это:
using (var a = new A())
using (var b = new B())
{
/// ...
}
Может быть, вы просто показали простой пример, но я думаю, что следующий текст более читабелен.
using (StreamReader rdr = new StreamReader(args[0]))
using (StreamWriter wrt = new StreamWriter(args[1]))
{
// code
}
Вы можете сделать вложенные с помощью операторов
красивее, используя только одну пару фигурных скобок, например:
using (StreamReader rdr = new StreamReader(args[0]))
using (StreamWriter wrt = new StreamWriter(args[1]))
{
///...
}
Чтобы ответить на ваш вопрос, вам нужно избавиться от обратный порядок сложения.
Следовательно, вы не можете использовать HashSet
.
Кроме того, нет причин раскрывать список IDisposable
внешнему миру.
Следовательно, вам не следует наследовать какой-либо класс коллекции, а вместо этого поддерживать частный List
.
Затем у вас должны быть общедоступные методы Add
и Dispose
(и никакие другие методы), а затем просмотреть список в обратном порядке в Dispose
.
Несколько замечаний об общем принципе:
с помощью операторов
без дополнительных фигурных скобок Если у вас есть две переменные одного типа, вы можете использовать один оператор using:
using (Stream input = File.OpenRead ("input.dat"),
output = File.OpenWrite ("output.dat"))
{
}
Предположим, вы действительно хотите продолжить это:
Add
. HashSet
или какой-либо другой коллекции. У вас должен быть только список внутри класса как закрытая переменная-член. Dispose
ни один из остальных вызовов Dispose
выполняться не будет; с традиционным оператором using
каждый вызов Dispose
выполняется в собственном блоке finally
. В принципе, я думаю, что это плохая идея. Вложение на два уровня далеко не болезненно; гнездование трех должно быть редким; вложенность четырех или более настоятельно предполагает рефакторинг. Вместо того, чтобы пытаться справиться с болью, связанной с глубоким вложением, вам следует избегать этого в дизайне.
Я должен сказать, что не согласен с людьми, которые хотят использовать операторы один за другим, например:
using (var a = new StreamReader())
using (var b = new StreamWriter())
{
// Implementation
}
На мой взгляд, это очень нечитабельно - наличие любого блока кода, который не завернутый - это просто плохой стиль и может привести к проблемам, если все разработчики, работающие над ним, не будут очень осторожны.
Я бы поставил это в один ряд с чем-то вроде:
if (someBoolean) DoSomething();
{
// Some code block unrelated to the if statement
}
Технически это не недействительно, но смотреть на это ужасно.
Я согласен с тем, что концепция MultiDispose, вероятно, не лучшая идея из-за того, что это не общепринятый шаблон, но я определенно не пошел бы по этому пути. Если вы не можете разбить вещи на более мелкие куски, я бы посоветовал просто жить с вложенными использованиями.
Лично меня это свело бы с ума. Если вы считаете, что вложенные операторы using раздражают, вы можете вернуться к синтаксису try / finally. Методы Dispose не должны генерировать исключения, поэтому вы можете предположить, что несколько одноразовых предметов не нужно будет индивидуально заключать в блоки try / finally.
Также стоит отметить, что вам нужен только один набор скобок для смежных блоков using, например:
using (var stream = File.Open(...))
using (var reader = new StreamReader(stream)) {
// do stuff
}