Introdução ao Destructor em C #

No artigo Destrutor em C #, como o nome sugere, destruidores são os métodos em C # que destroem os objetos. Se os objetos não forem mais necessários, o destruidor será chamado para destruir esses objetos da classe. O destruidor será chamado automaticamente pelo coletor de lixo e destruirá objetos.

Sintaxe:

class Demo
(
// other methods
~Demo() // destructor
(
// your code
)
)
C# destructor is a shortcut of Finalize( ) method. So when you declare destructor
~Demo() // destructor
(
// your code
)
C# compiler will translate it to:
protected override void Finalize()
(
try
(
// your code
)
finally
(
base.Finalize();
)
)

O destruidor é representado por ~ (til).

Propriedades do destruidor em c #

A seguir estão as propriedades do destruidor:

  1. Os destruidores não podem ter parâmetros e modificadores de acesso.
  2. Cada classe deve consistir em apenas um destruidor.
  3. Os destruidores não podem ser sobrecarregados ou herdados.
  4. O nome do destruidor é sempre o mesmo que o nome da classe e não tem tipo de retorno.
  5. O destruidor usa o método Finalize e invocado pelo Garbage Collector quando os objetos não são mais necessários.
  6. O destruidor segue o padrão inverso. No destruidor, a classe derivada é chamada primeiro e depois a classe base.

Como o destruidor funciona em c #?

Aqui estão alguns exemplos que mostram como ele funciona em c #.

Exemplo 1

Código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
(
class person
(
//variables
public string name;
public int age;
public person(string name, int age) //parametrized constructor
(
this.name = name;
this.age = age;
)
public string getName()
(
return this.name;
)
public int getAge()
(
return this.age;
)
~person() // destructor
(
Console.WriteLine("Destructor has been invoked");
)
)
class Program
(
// main method
static void Main(string() args)
(
person Details = new person("Joe", 28);
Console.WriteLine(Details.getName());
Console.WriteLine(Details.getAge());
)
)
)

No exemplo acima, o construtor parametrizado é inicializado com o nome e a idade do parâmetro, onde esta é uma palavra-chave referente às variáveis ​​de classe. Depois que o destruidor é criado com o mesmo nome que o nome da classe e o símbolo ~. No método principal, há um objeto da pessoa da classe. Depois de obter o nome e a idade de uma pessoa, os objetos não são mais necessários. Então, está sendo chamado destruidor que destrói os objetos e desaloca suas memórias.

Resultado:

Exemplo 2

Código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
anmespace Destructor
(
class person
(
// variables
public string name;
public int age;
public person(string name, int age) // parameterized constructor
(
this.name = name;
this.age = age;
)
public string getName()
(
return this.name;
)
public int getAge()
(
return this.age;
)
~person() //destructor
(
Console.WriteLine("Descructor has been invoked");
)
)
class Program
(
// Main method
static void Main(string() args)
(
person Details = new person("Joe", 28); // first object
person Details1 = new person("John", 20);
Console.WriteLine(Details.getName());
Console.WriteLine(Details.getAge());
Console.WriteLine(Details1.getName());
Console.WriteLine(Details1.getAge());
)
)
)

Este exemplo é quase o mesmo que o exemplo anterior, mas neste exemplo, existem dois objetos no método principal. Como sabemos, o construtor é executado para todos os objetos e a mesma coisa também é aplicada ao destruidor. Nesse caso, o destruidor está sendo chamado duas vezes e desaloca a memória de cada objeto.

Resultado:

Exemplo 3

Código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
(
public class Parent
(
~Parent() // base destructor
(
Console.WriteLine("Parent.~Parent()");
)
)
public class Child : Parent
(
~Child() // derived destructor
(
Console.WriteLine("Child.~Child()");
)
)
public class MainClass
(
static void Main()
(
Child child = new Child();
)
)
)

No exemplo acima, é definida a classe pai que possui um destruidor. Em seguida, a classe filho herda a classe pai e também consiste em um destruidor. Portanto, o destruidor filho chama automaticamente o destruidor de base.

Nos construtores, o construtor de base é chamado primeiro. Por exemplo, se tivermos a classe base A que é herdada pela classe B, portanto, no caso do construtor, a classe A é chamada primeiro e depois a classe B. No entanto, no caso do destruidor, a classe B (classe derivada) é chamada primeiro antes da classe A ( classe base).

Outro exemplo de execução de ordem: -

Código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
(
class Tree
(
~Tree()
(
System.Console.WriteLine("This is the first destructor");
)
)
class Branch: Tree
(
~Branch()
(
System.Console.WriteLine("This is the second destructor");
)
)
class Flower: Branch
(
~Flower()
(
System.Console.WriteLine("This is the third destructor");
)
)
class Test
(
static void Main()
(
Flower f= new Flower();
)
)
)

Resultado:

Como você pode ver, o terceiro construtor é chamado inicialmente, seguido pelo segundo e pelo primeiro.

Exemplo 4

Código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
(
class Example
(
public Example()
(
// constructor
Console.WriteLine("Object Created");
)
// Destructor
~Example()
(
Console.WriteLine("Object Destroyed");
)
)
class Program
(
public static void Sample()
(
Example ex = new Example();
)
static void Main(string() args)
(
Sample();
GC.Collect();
Console.ReadLine();
)
)
)

Resultado:

O destruidor desaloca a memória do objeto se eles não forem necessários no final do programa. Mas, às vezes, se usarmos GC.Collect () no meio da execução do programa, ele destruirá objetos no meio e desalocará a memória desses objetos. O destruidor pode ser chamado implicitamente ou explicitamente. Mas não há necessidade de destruir os objetos explicitamente, pois o C # fornece coleta de lixo. No entanto, quando terminar os recursos não gerenciados, será necessário liberá-los explicitamente. Não há necessidade de chamar ou caso de recursos gerenciados. Use destruidor para manipular recursos não gerenciados. O Garbage Collector chamará destruidor, pois consiste em uma lista de objetos que possuem um destruidor. Portanto, sempre que um objeto é criado ou destruído, essa lista é atualizada. Se houver um objeto na fila, ele será coletado pelo coletor de lixo após a execução do destruidor.

Conclusão

O principal objetivo do destruidor é liberar a memória dos objetos após sua execução. Portanto, existem ações diferentes executadas no destruidor, como recuperar o espaço, liberar recursos de rede e bloqueios de recursos, etc. Destrutores devem ser usados ​​para liberar recursos não gerenciados, em vez de recursos gerenciados.

Artigo recomendado

Este foi um guia para o Destructor em C #. Aqui discutimos a introdução, as propriedades e os Exemplos de destruidor em C #. Você também pode consultar nossos outros artigos sugeridos para saber mais -

  1. Introdução ao Destructor em Java
  2. Herança em C # | Os 4 principais tipos
  3. Copiar Construtor em C # (exemplos)
  4. O que é multithreading em c #? | Vantagens
  5. Destruidor em Python (vantagens com exemplo)
  6. Modificadores de acesso em PHP
  7. Tipos de construtor em C # com implementação de código
  8. Criação e métodos de multithreading em C #