Menu
Coddy logo textTech

Using vs. Try-Finally

Часть раздела Логика и управление потоком путешествия по C# на Coddy — урок 28 из 66.

Оба оператора using и блоки try-finally помогают управлять ресурсами, которые необходимо правильно освобождать. Оператор using предоставляет более чистый и краткий способ обеспечения правильной очистки объектов IDisposable.

Давайте сначала рассмотрим подход try-finally. Здесь StreamReader — это класс, который читает текст из файла — он удерживает открытый дескриптор файла, который является ресурсом и должен быть освобождён после использования:

StreamReader reader = null;
try
{
    reader = new StreamReader("file.txt");
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}
finally
{
    if (reader != null)
    {
        reader.Dispose();
    }
}

Блок finally гарантирует, что Dispose() будет вызван для освобождения дескриптора файла, даже если внутри блока try возникнет исключение.

Оператор using упрощает этот шаблон. Он объявляет и инициализирует ресурс в скобках и автоматически вызывает Dispose() при выходе из блока — независимо от того, нормально или из-за исключения:

using (StreamReader reader = new StreamReader("file.txt"))
{
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}

Это эквивалентно примеру с try-finally выше, но с меньшим количеством котелочного кода.

Оператор using автоматически вызывает Dispose() при выходе из блока, даже если возникает исключение. Он заменяет шаблон очистки try-finallyне try-catch. Если вам также нужно обрабатывать исключения, вы все еще можете обернуть блок using внутри try-catch.

challenge icon

Задание

Легко

Создайте метод с именем processFile, который:

  1. Принимает имя файла в качестве строкового параметра
  2. Использует оператор using с StreamReader для чтения всех строк из файла
  3. Возвращает количество строк в файле
  4. Если возникает FileNotFoundException, выведите "File not found" и верните -1

Шпаргалка

Оператор using обеспечивает автоматическую очистку ресурсов для объектов IDisposable, гарантируя вызов Dispose() даже в случае возникновения исключений. Он заменяет многословный шаблон try-finally.

Подход try-finally:

StreamReader reader = null;
try
{
    reader = new StreamReader("file.txt");
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}
finally
{
    if (reader != null)
    {
        reader.Dispose();
    }
}

Оператор using (более чистый подход):

using (StreamReader reader = new StreamReader("file.txt"))
{
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}

Оба подхода обеспечивают вызов Dispose() при выходе из блока. Оператор using обрабатывает это автоматически, устраняя необходимость в ручной проверке на null и блоке finally.

Ключевые моменты:
using заменяет try-finally — не try-catch
try-catch по-прежнему можно комбинировать с using для обработки исключений
StreamReader читает текстовые файлы и реализует IDisposable, что делает его идеальным для использования с using

Попробуйте сами

using System;
using System.IO;

class ProcessFile
{
    public static int processFile(string filename)
    {
        // Напишите свой код здесь
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком