MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Construcția using

În tema anterioară, unde am discutat despre implementarea metodei Dispose, s-a menționat că pentru a o apela putem folosi următoarea construcție try..finally:

Test();

void Test()
{
   Person? tom = null;
   try
   {
       tom = new Person("Tom");
   }
   finally
   {
       tom?.Dispose();
   }
}
public class Person : IDisposable
{
   public string Name { get;}
   public Person(string name) => Name = name;

   public void Dispose() => Console.WriteLine($"{Name} has been disposed");
}

Totuși, sintaxa C# oferă și o construcție sinonimică pentru apelarea automată a metodei Dispose - construcția using:

using (Person tom = new Person("Tom"))
{
}

Construcția using definește un bloc de cod și creează un obiect de un anumit tip, care implementează interfața IDisposable, în special metoda sa Dispose. La finalizarea blocului de cod, metoda Dispose este apelată automat pentru obiectul respectiv.

Este important de menționat că această construcție se aplică doar pentru tipurile care implementează interfața IDisposable.

Utilizarea construcției using:

Test();

void Test()
{
   using (Person tom = new Person("Tom"))
   {
       // variabila tom este disponibilă doar în blocul using
       // unele acțiuni cu obiectul Person
       Console.WriteLine($"Name: {tom.Name}");
   }
   Console.WriteLine("Sfârșitul metodei Test");
}
public class Person : IDisposable
{
   public string Name { get;}
   public Person(string name) => Name = name;

   public void Dispose() => Console.WriteLine($"{Name} has been disposed");
}

Output în consolă:

Name: Tom
Tom has been disposed
Sfârșitul metodei Test

Aici observăm că la finalizarea blocului using, metoda Dispose este apelată pentru obiectul Person. În afara blocului de cod using, obiectul tom nu mai există.

Începând cu versiunea C# 8.0, putem seta ca domeniul de aplicare să fie întreaga zonă de vizibilitate, de exemplu, metoda:

Test();

void Test()
{
   using Person tom = new Person("Tom");
   
   // variabila tom este disponibilă doar în blocul using
   // unele acțiuni cu obiectul Person
   Console.WriteLine($"Name: {tom.Name}");
   Console.WriteLine("Sfârșitul metodei Test");
}
public class Person : IDisposable
{
   public string Name { get;}
   public Person(string name) => Name = name;

   public void Dispose() => Console.WriteLine($"{Name} has been disposed");
}

În acest caz, using informează compilatorul că variabila declarată trebuie eliberată la sfârșitul domeniului de vizibilitate - adică la sfârșitul metodei Test. În consecință, output-ul în consolă va fi:

Name: Tom
Sfârșitul metodei Test
Tom has been disposed

Eliberarea mai multor resurse

Pentru eliberarea mai multor resurse, putem folosi construcții using imbricate. De exemplu:

void Test()
{
   using (Person tom = new Person("Tom"))
   {
       using (Person bob = new Person("Bob"))
       {
           Console.WriteLine($"Person1: {tom.Name}    Person2: {bob.Name}");
       } // apelarea metodei Dispose pentru obiectul bob
   } // apelarea metodei Dispose pentru obiectul tom
   Console.WriteLine("Sfârșitul metodei Test");
}

În acest caz, ambele construcții using creează obiecte de același tip, dar pot fi și tipuri de date diferite, cu condiția ca acestea să implementeze interfața IDisposable.

Putem simplifica această definiție:

void Test()
{
   using (Person tom = new Person("Tom"))
   using(Person bob = new Person("Bob"))
   {
       Console.WriteLine($"Person1: {tom.Name}    Person2: {bob.Name}");
   } // apelarea metodei Dispose pentru obiectele bob și tom
   Console.WriteLine("Sfârșitul metodei Test");
}

Și, așa cum s-a menționat anterior, în C# putem seta ca domeniul de aplicare pentru obiectele create în construcția using să fie întreaga metodă:

private static void Test()
{
   using Person tom = new Person { Name = "Tom" };
   using Person bob = new Person { Name = "Bob" };
   
   Console.WriteLine($"Person1: {tom.Name}    Person2: {bob.Name}");
   
   Console.WriteLine("Sfârșitul metodei Test");
} // apelarea metodei Dispose pentru obiectele bob și tom
← Lecția anterioară Lecția următoare →