Одно из нововведений в 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) переменных методов.