C#

[C#]소멸자(destructor)

DevStory 2022. 5. 2.

소멸자(destructor)

소멸자는 클래스 이름과 동일하지만 메서드 이름 앞에 물결표(~)가 존재하는 특수한 메서드입니다. C#의 생성자는 클래스의 객체가 생성될 때 호출됩니다. 반면에 소멸자는 클래스의 객체가 소멸될 때 실행됩니다.

 

생성자 및 소멸자는 클래스 이름과 동일하지만, 생성자와 소멸자를 구분하기 위해 소멸자 메서드 이름 앞에 물결표(~) 키워드가 사용됩니다.

class Person
{
  Person()
  {
    // 생성자
  }

  ~Person()
  {
  // 소멸자
  }
}

소멸자 특징

  1. 소멸자는 매개변수와 접근 지정자(접근 제한자)를 가질 수 없습니다.
  2. 각 클래스는 여러 개의 소멸자를 가질 수 없습니다.
  3. 소멸자는 오버로드되거나 상속될 수 없습니다.
  4. 소멸자 이름은 항상 클래스 이름과 동일하며 반환 타입이 없습니다.
  5. 소멸자는 Finalize 메서드를 사용하고 객체가 더 이상 필요하지 않을 때 가비지 컬렉터(Garbage Collector)에 의해 호출됩니다.

객체가 소멸되는 경우

  1. 프로그램 실행이 끝나면 프로그램과 관련된 모든 객체는 가비지 컬렉터에 의해 파괴됩니다.
  2. 가비지 컬렉터의 암시적 호출은 메모리가 가득 찬 경우 프로그램 실행 중 발생합니다. 프로그램에서 사용되지 않는 객체를 식별하고 제거합니다.
  3. 가비지 컬렉터의 명시적 호출은 GC.Collect()를 사용하여 프로그램 실행 도중에 실행될 수 있습니다. 

소멸자 예제 1. 기본

다음은 두 개의 객체를 생성하고 생성자와 소멸자에서 Console.WriteLine()을 호출합니다.

class Person
{
  public Person()
  {
    Console.WriteLine("생성자 호출!");
  }

  ~Person()
  {
    Console.WriteLine("소멸자 호출!");
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person();
    Person person2 = new Person();
  }
}

실행 결과

생성자 호출!
생성자 호출!

위 코드를 실행하면 두 개의 객체를 생성했으므로 생성자가 두 번 호출되었고 소멸자는 호출되지 않은 것처럼 보입니다.

 

소멸자는 .NET 5(.NET Core 포함) 이상 버전인 경우 애플리케이션이 종료될 때 소멸자를 호출하지 않습니다. 그러므로 콘솔 창에서 소멸자가 호출되었는지 확인할 수 없습니다. .NET 5(.NET Core 포함) 이상 버전에서 소멸자를 강제로 실행하기 위해서는 GC.Collect()를 호출해야 합니다.

반응형

소멸자 예제 2. 상속 구조

다음은 상속 구조의 클래스 객체가 소멸되는 순서입니다.

public class Parent
{
  ~Parent()
  {
    Console.WriteLine("부모 클래스 소멸자 호출!");
  }
}

public class Child : Parent
{
  ~Child() 
  {
    Console.WriteLine("자식 클래스 소멸자 호출!");
  }
}
    
class Program
{
  static void Main(string[] args)
  {
    Child child = new Child();
  }
}

부모 클래스인 Parent와 자식 클래스인 Child가 존재하며, Child 클래스 객체를 생성했습니다. 소멸자 호출 순서는 자식 클래스인 Child의 소멸자가 먼저 호출되고 부모 클래스 Parent의 소멸자가 차례로 호출됩니다.


소멸자 예제 3. 명시적 호출 

다음 예제는 GC.collect()를 호출하여 강제로 가비지 컬렉터를 실행합니다.

public class Parent
{
  ~Parent()
  {
    Console.WriteLine("부모 클래스 소멸자 호출!");
  }
}

public class Child : Parent
{
  ~Child() 
  {
    Console.WriteLine("자식 클래스 소멸자 호출!");
  }
}

class Program
{
  public static void Sample()
  {
    Child child = new Child();
  }
        
  static void Main(string[] args)
  {
    Sample();
    GC.Collect();
    Console.ReadLine();
  }
}

실행 결과

자식 클래스 소멸자 호출!
부모 클래스 소멸자 호출!

GC.Collect()를 호출하여 콘솔 창에서 소멸자 호출 순서를 확인할 수 있습니다. 자식 클래스의 소멸자가 호출 후 부모 클래스 소멸자가 호출되었습니다.

 

위 예제처럼 소멸자는 명시적으로 호출할 수 있지만, C#에서 가비지 콜렉터를 제공하므로 명시적으로 호출할 필요가 없습니다.

반응형

'C#' 카테고리의 다른 글

[C#]복사 생성자(Copy Constructor)  (0) 2022.05.05
[C#]생성자(Constructor)  (0) 2022.05.05
[C#]DataTable을 List로 변환  (0) 2022.05.01
[C#]텍스트 파일 쓰기  (0) 2022.05.01
[C#]람다식, 람다표현식(Lambda expression)  (0) 2022.05.01

댓글