Programming/.NET

클래스의 생성자는 클래스명과 같은 메서드를 정의함으로서 구현할 수 있습니다.

 

class MyClass
{
    public MyClass()
    {

    }
}

 

생성자는 말 그대로 클래스의 개체가 생성될때 호출되는 메서드입니다. 여기에 각종 변수의 초기화나 혹은 필요한 매개변수를 받아 클래스에서 사용되는 데이터를 초기화 하는 것이 가능합니다.

 

class MyClass
{
    public MyClass(int i, int j)
    {
        MyValue = i + j;
    }

    public int MyValue
    {
        get;
        set;
    }
}

 

예제에서 클래스는 개체생성시 두개의 매개변수를 받아 MyValue라는 속성값을 초기화 하도록 하였습니다.

 

static void Main(string[] args)
{
    MyClass m = new MyClass(10, 20);
    Console.WriteLine(m.MyValue);
}

 

소멸자는 GC에 의해 해당 개체의 자원을 해제할때 호출되는 메서드입니다. 이 메서드는 클래스이름앞에 ~문자만 붙이면 소멸자 메서드가 됩니다.

 

class MyClass
{
    public MyClass(int i, int j)
    {
        MyValue = i + j;
    }

    public int MyValue
    {
        get;
        set;
    }

    ~MyClass()
    {

    }
}

 

소멸자는 임의로 호출하는 것이 불가능하며 GC가 수행될때 호출됩니다. 소멸자는 그 특성으로 인해 소멸자에서 뭔가를 임의로 처리하는 경우는 거의 없습니다. 간혹 비관리메모리를 사용한 경우 GC에 의해 해제될 수 없기에 소멸자에서 명시적으로 해제에 필요한 코드를 담는 경우가 있기는 하지만 활용도가 크지는 않습니다.

 

class MyClass : IDisposable
{
    IntPtr myMemory;

    public MyClass()
    {
        myMemory = Marshal.AllocCoTaskMem(1024);
    }

    public void Dispose()
    {
        Marshal.FreeCoTaskMem(myMemory);
    }

    ~MyClass()
    {
        Dispose();
    }
}

 

소멸자가 있는 클래스에 new로 개체를 생성하면 이 개체를 힙에 저장하고 동시에 '종료큐'라고 하는 곳에도 개체를 등록하게 됩니다. GC가 이 개체를 힙에서 제거하고자 할때 종료큐에 들어간 개체를 Freachable에 옮기게 되면 CLR에 의해 생성된 스레드가 Freachable안에 존재하는 개체의 소멸자를 호출한뒤 Freachable안에서 개체를 제거하게 됩니다. 그리고 힙에 존재하는 개체는 GC가 실행될때 비로소 힙에서 제거됩니다. 이 복잡한 과정때문에 소멸자가 존재하는 클래스는 GC에 부담스럽게 작용하고 때문에 꼭 필요하지 않다면 소멸자를 별도로 생성하는건 권장하지 않습니다.

 

하지만 만약 클래스의 Dispose() 메서드가 명시적으로 호출될 수 있는 상황이고 이때 GC가 소멸자를 다룰 필요가 없는 경우라면 Dispose() 메서드에서 GC의 SuppressFinalize() 메서드를 호출하여 종료큐에서 개체를 제거하도록 할 수 있습니다. 이렇게 되면 GC가 소멸자를 고려할 필요가 없으므로 GC의 부담을 줄여줄 수 있게 됩니다.

 

class MyClass : IDisposable
{
    IntPtr myMemory;

    public MyClass()
    {
        myMemory = Marshal.AllocCoTaskMem(1024);
    }

    public void Dispose()
    {
        objectRemove(true);
    }

    private void objectRemove(bool self_call)
    {
        Marshal.FreeCoTaskMem(myMemory);

        if (self_call)
            GC.SuppressFinalize(this);
    }

    ~MyClass()
    {
        objectRemove(false);
    }
}

'Programming > .NET' 카테고리의 다른 글

[C#] fixed  (0) 2018.06.13
[C#] DateTime  (0) 2018.05.29
[C#] 생성자와 소멸자  (0) 2018.05.23
[C#] 개체의 생성과 해제  (0) 2018.05.15
[C#] 호출자 정보 (CallerMemberName / CallerFilePath / CallerLineNumber)  (0) 2018.05.08
[C#] 람다식 (Lambda expression)  (0) 2018.05.02
0 0