Новые возможности C# 8 – using в объявлении переменных

C# logoОдно из нововведений в C# 8 – это возможность использовать ключевое using в объявлении переменных. Давайте разберемся для чего это необходимо и как работает такой код.

Ключевое слово using в объявлении переменной это, по сути, синтаксический сахар. Его использование заменяет конструкцию using(…) { … } и делает код более удобным для чтения. Областью действия объявления using является код метода от места объявления переменной до его конца.

Рассмотрим на примере:

public override string Serialize(DataContainer container)
{
    this.ValidateContainer(container);

    using var memoryStream = new MemoryStream();
    using var reader = new StreamReader(memoryStream);

    var serializer = new DataContractSerializer(container.GetType());
    serializer.WriteObject(memoryStream, container);
    memoryStream.Position = 0;
    return reader.ReadToEnd();
}

Методы Disposе() у переменных memoryStream и reader будут вызваны непосредственно перед завершением метода Serialize(…). Таким образом, приведённый код будет полностью эквивалентен следующему варианту:

public override string Serialize(DataContainer container)
{
    this.ValidateContainer(container);

    using (var memoryStream = new MemoryStream())
    using (var reader = new StreamReader(memoryStream))
    {
        var serializer = new DataContractSerializer(container.GetType());
        serializer.WriteObject(memoryStream, container);
        memoryStream.Position = 0;
        return reader.ReadToEnd();
    }
}

Стоит напомнить, что конструкция using(…) { … } так же является синтаксическим сахаром, который при компиляции кода разворачивается в try { var x = … } finally { ((IDisposable)x).Dispose(); }

Не все случаи использования конструкции using(…) {…} можно переписать с использованием нового варианта объявления переменных. Это связано, опять же, с областью действия. Например:

public void Process(DataContainer container)
{
    this.ValidateContainer(container);

    using (var resource = new ProcessingResource())
    {
        …
    }

    this.DoPostPrcessing(container);
}

Если заменить конструкцию на объявление, то в зону действия using попадет метод DoPostPrcessing() и ресурсы не будут освобождены до окончания его выполнения. Поведение метода Process(...) изменится.

Кроме того, запрещено использовать объявление using в выходных (out) переменных методов.

Добавить комментарий