Как мне вернуть StringWriter, когда я не могу его клонировать?

Мой код выглядит следующим образом. Очевидно, я не могу написать "ОК", потому что объект был удален. Я не могу вернуть sw.Clone(), потому что клон не существует. Если я не использую использование, то в любой момент между = new и return (например, итерация и запись в объект, как не делает мой пример) может иметь исключение, и, следовательно, не избавляться от объекта.

Должен ли я определить sw вне блока try и проверить, является ли он пустым, а затем поместить в блок catch? Это похоже на излишнюю работу. Есть ли способ лучше? Это единственный способ?

    static void func1()
    {
        using (var sw = func2())
        {
            sw.WriteLine("Ok");
        }
    }
    static StringWriter func2()
    {
        using (var sw = new StringWriter())
        {
            return sw;
        }
    }

5 ответов

Решение

Вы можете пересмотреть возвращение StringWriter. Хотя у вас может быть несколько мест, где вам нужна эта дополнительная функциональность, мне кажется, что сантехника торчит посреди гостиной. Он не должен быть частью общедоступного API и даже неуклюж, даже в частном.

С учетом сказанного, если он вам нужен, не закрывайте и не удаляйте его, прежде чем возвращать, и не используйте блок using. Используйте блок try/catch (т. Е. Dispose в catch, а не предложение finally).

К вашему сведению: реализация закрытия StringWriter вызывает метод Dispose, передавая истинное значение. Почему бы просто не вернуть второй sw в вызывающий метод и вызвать close, который будет эквивалентен.

Я собираюсь предположить, что это общий вопрос о возвращении объектов, которые реализуют IDisposableи не вопрос про func1 а также func2,

Использовать using блокировать вокруг чего-либо реализации IDisposable если ты

  1. Создайте это и
  2. Больше не нужно, когда ваш метод возвращает

В вашем случае вы создаете его, но он должен существовать после возврата вашего метода. В этом случае не используйте блок using в методе, который создает объект. Затем вызывающая сторона несет ответственность за удаление объекта, что, как я вижу, уже происходит.

Избавьтесь от второго, используя блок. Просто делать

StringWriter sw = new StringWriter();
return sw;

StringWriter удаляется, если вы определяете его в блоке using.

Создайте класс с помощью методов func1 и func2, сделайте этот IDisposable, инициализируйте StringWriter в конструкторе и избавьтесь от него в методе Dispose вашего класса.

Это предполагает, что вы пишете в StringWriter более чем одним методом.

Другие вопросы по тегам