클래스의 인스턴스인 개체는 키워드를 New
사용하여 만들어집니다. 초기화 작업은 새 개체를 사용하려면 먼저 수행해야 하는 경우가 많습니다. 일반적인 초기화 작업에는 파일 열기, 데이터베이스 연결 및 레지스트리 키 값 읽기가 포함됩니다. Visual Basic은 생성자 (초기화를 제어할 수 있는 특수 메서드)라는 프로시저를 사용하여 새 개체의 초기화를 제어합니다.
개체가 범위를 벗어나면 CLR(공용 언어 런타임)에서 해제됩니다. Visual Basic은 소멸자라는 프로시저를 사용하여 시스템 리소스의 릴리스를 제어합니다. 생성자와 소멸자는 함께 강력하고 예측 가능한 클래스 라이브러리 만들기를 지원합니다.
생성자 및 소멸자 사용
생성자와 소멸자는 개체의 생성 및 소멸을 제어합니다. Visual Basic에서 Sub New
및 Sub Finalize
프로시저는 개체를 초기화하고 파괴합니다. 이러한 프로시저는 Visual Basic 6.0 및 이전 버전에서 사용된 Class_Initialize
및 Class_Terminate
메서드를 대체합니다.
하위 새로 만들기
Sub New
생성자는 클래스를 만들 때 한 번만 실행할 수 있습니다. 동일한 클래스 또는 파생 클래스에서 다른 생성자의 첫 번째 코드 줄 이외의 위치에서 명시적으로 호출할 수 없습니다. 또한 메서드의 코드는 항상 클래스의 Sub New
다른 코드 앞에 실행됩니다. 클래스에 대해 명시적으로 Sub New
프로시저를 정의하지 않으면 Visual Basic은 런타임 중에 생성자를 암시적으로 Sub New
생성합니다.
클래스에 대한 생성자를 만들려면 클래스 정의의 아무 곳이나 명명된 Sub New
프로시저를 만듭니다. 매개 변수가 있는 생성자를 만들려면 다음 코드와 같이 다른 프로시저의 인수를 지정하는 Sub New
것과 마찬가지로 인수의 이름과 데이터 형식을 지정합니다.
Sub New(ByVal s As String)
생성자는 다음 코드와 같이 자주 오버로드됩니다.
Sub New(ByVal s As String, i As Integer)
다른 클래스에서 파생된 클래스를 정의하는 경우 기본 클래스에 매개 변수를 사용하지 않는 액세스 가능한 생성자가 없는 한 생성자의 첫 번째 줄은 기본 클래스의 생성자에 대한 호출이어야 합니다. 예를 들어 위의 생성자를 포함하는 기본 클래스에 대한 호출은 다음과 같습니다 MyBase.New(s)
. 그렇지 않으면 MyBase.New
선택 사항이며 Visual Basic 런타임은 암시적으로 호출합니다.
부모 개체의 생성자를 호출하는 코드를 작성한 후 프로시저에 Sub New
추가 초기화 코드를 추가할 수 있습니다.
Sub New
는 매개 변수가 있는 생성자로 호출될 때 인수를 수락할 수 있습니다. 이러한 매개 변수는 생성자를 호출하는 프로시저에서 전달됩니다(예: Dim AnObject As New ThisClass(X)
.).
하위 종료
개체를 해제하기 전에 CLR은 Finalize
프로시저를 정의하는 개체에 대해 Sub Finalize
메서드를 자동으로 호출합니다. 이 메서드는 Finalize
파일을 닫고 상태 정보를 저장하는 코드와 같이 개체가 제거되기 직전에 실행해야 하는 코드를 포함할 수 있습니다.
Sub Finalize
를 실행하면 성능 저하가 있으므로, 개체를 명시적으로 해제해야 할 때만Sub Finalize
메서드를 정의해야 합니다.
비고
CLR의 가비지 수집기는 CLR 환경 외부에서 운영 체제가 직접 실행하는 관리되지 않는 개체를 삭제하지 않으며 삭제할 수 없습니다. 다른 관리되지 않는 개체를 다른 방식으로 삭제해야 하기 때문입니다. 해당 정보는 관리되지 않는 개체와 직접 연결되지 않습니다. 개체에 대한 설명서에 있어야 합니다. 관리되지 않는 개체를 사용하는 클래스는 메서드 Finalize
에서 삭제해야 합니다.
Finalize
소멸자가 속한 클래스 또는 파생 클래스에서만 호출할 수 있는 보호된 메서드입니다. 개체가 제거되면 시스템이 자동으로 호출 Finalize
되므로 파생 클래스의 Finalize
구현 외부에서 명시적으로 호출 Finalize
해서는 안 됩니다.
Class_Terminate
는 개체가 아무 것도 아닌 상태로 설정되면 즉시 실행되지만, 일반적으로 개체가 범위를 잃을 때와 Visual Basic에서 Finalize
소멸자를 호출하는 시점 사이에 지연이 발생합니다. Visual Basic .NET은 리소스를 즉시 해제하기 위해 언제든지 명시적으로 호출할 수 있는 두 번째 종류의 소멸자를 IDisposable.Dispose허용합니다.
비고
Finalize
소멸자가 예외를 발생시키면 안 됩니다. 애플리케이션은 이를 처리할 수 없으며 종료될 수 있습니다.
클래스 계층 구조에서 New 및 Finalize 메서드가 작동하는 방식
클래스의 인스턴스를 만들 때마다 CLR(공용 언어 런타임)은 해당 개체에 있는 경우 명명된 New
프로시저를 실행하려고 시도합니다.
New
는 개체의 다른 코드가 실행되기 전에 새 개체를 초기화하는 데 사용되는 프로시저라는 constructor
형식입니다.
New
생성자를 사용하여 파일을 열고, 데이터베이스에 연결하고, 변수를 초기화하고, 개체를 사용하려면 먼저 수행해야 하는 다른 작업을 처리할 수 있습니다.
파생 클래스의 인스턴스가 Sub New
이 생성되면 기본 클래스의 생성자가 먼저 실행되고 그 다음에 파생 클래스의 생성자가 실행됩니다. 이는 생성자의 첫 번째 코드 줄이 Sub New
구문을 MyBase.New()
사용하여 클래스 계층 구조에서 바로 위에 있는 클래스의 생성자를 호출하기 때문에 발생합니다.
Sub New
그런 다음 기본 클래스의 생성자에 도달할 때까지 클래스 계층의 각 클래스에 대해 생성자가 호출됩니다. 이때 기본 클래스에 대한 생성자의 코드가 실행되고 모든 파생 클래스의 각 생성자의 코드가 실행되고 가장 파생된 클래스의 코드가 마지막으로 실행됩니다.
개체가 더 이상 필요하지 않은 경우 CLR은 메모리를 Finalize 해제하기 전에 해당 개체에 대한 메서드를 호출합니다. 이 Finalize 메서드는 상태 정보 저장, 파일 및 데이터베이스에 대한 연결 닫기 및 개체를 해제하기 전에 수행해야 하는 기타 작업과 같은 정리 작업을 수행하기 때문에 호출 destructor
됩니다.
IDisposable 인터페이스
클래스 인스턴스는 Windows 핸들 및 데이터베이스 연결과 같이 CLR에서 관리되지 않는 리소스를 제어하는 경우가 많습니다. 이 리소스는 객체가 가비지 수집기에 의해 파괴될 때 해제되도록 클래스의 Finalize
메서드에서 처리되어야 합니다. 그러나 가비지 수집기는 CLR에 더 많은 사용 가능한 메모리가 필요한 경우에만 개체를 삭제합니다. 즉, 개체가 범위를 벗어난 후 오랜 시간이 지나야 리소스가 해제될 수 있습니다.
가비지 수집을 보완하기 위해 클래스는 인터페이스를 구현하여 시스템 리소스를 적극적으로 관리하는 메커니즘을 IDisposable 제공할 수 있게 됩니다.
IDisposable 에는 하나의 메서드가 Dispose있습니다. 이 메서드는 클라이언트가 개체 사용을 완료할 때 호출해야 합니다. 이 메서드를 Dispose 사용하여 리소스를 즉시 해제하고 파일 및 데이터베이스 연결 닫기와 같은 작업을 수행할 수 있습니다. 소멸자와 달리, Finalize
메서드는 자동으로 호출되지 않습니다. 리소스를 즉시 해제하려면 클래스의 클라이언트가 명시적으로 호출 Dispose 해야 합니다.
IDisposable 구현
인터페이스를 구현하는 클래스에는 IDisposable 다음 코드 섹션이 포함되어야 합니다.
개체가 삭제되었는지 여부를 추적하기 위한 필드입니다.
Protected disposed As Boolean = False
클래스의 리소스를 해제하는 Dispose의 오버로드입니다. 이 메서드는 기본 클래스의 Dispose 메서드 및
Finalize
메서드에 의해 호출되어야 합니다.Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposed Then If disposing Then ' Insert code to free managed resources. End If ' Insert code to free unmanaged resources. End If Me.disposed = True End Sub
Dispose 구현에는 다음 코드만 포함됩니다.
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub
메서드
Finalize
의 재정의로, 다음 코드만 포함합니다.Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
IDisposable을 구현하는 클래스에서 파생
인터페이스를 구현 IDisposable 하는 기본 클래스에서 파생되는 클래스는 삭제해야 하는 추가 리소스를 사용하지 않는 한 기본 메서드를 재정의할 필요가 없습니다. 이 경우 파생 클래스는 파생 클래스의 Dispose(disposing)
리소스를 삭제하도록 기본 클래스의 메서드를 재정의해야 합니다. 이 재정의는 기본 클래스의 Dispose(disposing)
메서드를 호출해야 합니다.
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposed Then
If disposing Then
' Insert code to free managed resources.
End If
' Insert code to free unmanaged resources.
End If
MyBase.Dispose(disposing)
End Sub
파생 클래스는 기본 클래스의 Dispose 메서드와 Finalize
메서드를 재정의해서는 안 됩니다. 파생 클래스의 인스턴스에서 이러한 메서드가 호출될 때, 기본 클래스의 해당 메서드 구현은 파생 클래스의 Dispose(disposing)
메서드 재정의를 호출합니다.
가비지 수집 및 소멸자 종료
.NET Framework는 참조 추적 가비지 수집 메커니즘을 사용하여 사용하지 않는 리소스를 주기적으로 해제합니다. Visual Basic 6.0 및 이전 버전은 리소스를 관리하기 위해 참조 계산 이라는 다른 시스템을 사용했습니다. 두 시스템 모두 동일한 기능을 자동으로 수행하지만 몇 가지 중요한 차이점이 있습니다.
CLR은 시스템에서 이러한 개체가 더 이상 필요하지 않은 것으로 판단할 때 개체를 주기적으로 삭제합니다. 시스템 리소스가 부족할 때 개체가 더 빠르게 해제되고, 그렇지 않으면 개체가 덜 자주 해제됩니다. 개체가 범위를 잃을 때와 CLR이 해제되는 시점 사이의 지연은 Visual Basic 6.0 및 이전 버전의 개체와 달리 개체가 제거되는 시기를 정확하게 확인할 수 없음을 의미합니다. 이러한 상황에서 개체는 비결정적 수명을 가지고 있다고 합니다. 대부분의 경우 개체가 범위를 잃을 때 소멸자가 즉시 실행되지 않을 수 있다는 점을 Finalize
기억하기만 하면 비결정적 수명은 애플리케이션 작성 방법을 변경하지 않습니다.
가비지 수집 시스템 간의 또 다른 차이점은 Nothing
의 사용에 관한 것입니다. Visual Basic 6.0 및 이전 버전에서 참조 계산을 활용하기 위해, 프로그래머들은 때때로 Nothing
를 개체 변수에 할당하여 그 변수들이 보유한 참조를 해제했습니다. 변수가 개체에 대한 마지막 참조를 보유하면 개체의 리소스가 즉시 해제됩니다. 이후 버전의 Visual Basic에서는 이 프로시저가 여전히 중요한 경우가 있을 수 있지만 이를 수행하면 참조된 개체가 리소스를 즉시 해제하지 않습니다. 리소스를 즉시 해제하려면 사용 가능한 경우 개체의 Dispose 메서드를 사용합니다.
Nothing
를 변수로 설정해야 하는 유일한 경우는 가비지 수집기가 고립된 개체를 감지하는 데 걸리는 시간에 비해 변수의 수명이 긴 경우입니다.
참고하십시오
.NET