클래스 개념 및 구조
C# 언어의 클래스는 객체 지향의 핵심 요소로 개념 및 구조는 다음과 같다.
| 구분 | 설명 |
|---|---|
| 타입 분류 | 참조 타입이며, 인스턴스는 힙에 저장된다. |
| 구성 요소 | 상태(필드/속성)와 행위(메소드)를 캡슐화한다. |
| 객체 생성 | new 키워드를 사용하여 인스턴스를 생성한다. |
| 궁극적 상속 | 모든 클래스는 System.Object 클래스로부터 상속받는다. |
클래스 복사 방식
클래스 객체를 복사할 때, 참조 타입과 값 타입의 처리에 따라 두 가지 방식이 있다.
| 구분 | 얕은 복사(Shallow Copy) | 깊은 복사(Deep Copy) |
|---|---|---|
| 복사 대상 | 값 타입 필드와 참조만 복사한다. | 모든 필드(값 타입 및 참조 객체 데이터)를 재귀적으로 복사한다. |
| 참조 타입 처리 | 원본과 복사본이 같은 힙 메모리 주소를 공유한다. | 원본과 복사본이 완전히 새로운 독립된 객체를 가진다. |
| 독립성 | 낮음(한쪽 수정 시 다른 쪽 영향을 받는다.) | 높음(완벽히 독립적이다.) |
| 구현 방법 | object.MemberwiseClone() 메소드 사용 | ICloneable 인터페이스 구현 또는 수동으로 모든 필드에 대해 new 연산자 사용 |
| 주요 사용 | 객체가 값 타입 필드만 가지고 있으나, 참조 객체의 공유가 의도된 경우 | 객체 내부의 모든 상태가 독립적으로 유지되어야 하는 경우 |
생성자와 종료자
클래스 인스턴스의 생명 주기(Lifecycle) 시작과 끝에서 호출되는 함수 멤버이다.
| 구분 | 생성자(Constructor) | 종료자(Finalizer) |
|---|---|---|
| 호출 시점 | 객체가 생성될 때(메모리에 할당될 때 즉, 인스턴스화 되었을 때) | 객체가 소멸되기 직전(메모리에서 해제될 때) |
| 목적 | 객체의 초기 상태 설정 및 필요한 리소스 할당 | 비관리 리소스 해제 및 정리 작업 |
| 호출 주체 | new 키워드를 통해 개발자가 명시적으로 호출 | 가비지 컬렉터가 자동으로 호출 |
| 결정성 | 결정적(호출 시점이 명확하다.) | 비결정적(가비지 컬렉터 스케줄에 따른다.) |
| 표기 방법 | 클래스 이름과 동일 | C++ 언어 소멸자 문법 |
| 대안 | 해당 없음 | IDisposable 인터페이스와 Dispose() 메소드를 통한 명시적 해제가 권장된다. |
this 레퍼런스
this 레퍼런스는 객체가 자신을 지칭할 때 사용하는 키워드로 객체 외부에서는 객체의 필드나 메소드에 접근할 때 객체의 이름을 사용한다면, 객체 내부에서는 자신의 필드나 메소드에 접근할 때 this 키워드를 사용한다.
| 구분 | this 키워드 | this() 생성자 호출 |
|---|---|---|
| 용도 | 클래스 인스턴스 자신을 참조한다. | 같은 클래스의 다른 생성자를 호출한다. |
| 주요 사용 | 1. 메소드 내에서 필드와 매개 변수의 이름이 같을 때 필드를 구분 2. 현재 객체를 다른 메소드의 인수로 전달 |
생성자가 오버 로딩 시, 코드 중복을 피하고 초기화 로직을 하나로 통합하기 위해 사용 |
중첩 클래스와 분할 클래스
중첩 클래스(Nested Class)는 다른 클래스 내부에 정의된 클래스인 반면, 분할 클래스(Partial Class)는 partial 키워드를 사용해 하나의 클래스 정의를 여러 개의 물리적인 파일로 나누는 기능이다.
| 구분 | 중첩 클래스 | 분할 클래스 |
|---|---|---|
| 정의 | 다른 클래스 내부에 정의된 클래스 | 하나의 클래스 정의를 여러 개의 물리적인 파일로 나눌 수 있는 클래스 |
| 특징 | 중첩 클래스는 바깥 클래스의 멤버에도 접근할 수 있지만, 외부 클래스는 중첩 클래스의 private 멤버에 접근할 수 없다. | 컴파일러는 분할된 모든 파일을 모아 하나의 완전한 클래스로 컴파일한다. |
| 용도 | 캡슐화가 필요한 헬퍼 클래스 정의 | 1. 자동 생성 코드와 수동 작성 코드 분리 2. 대규모 클래스의 팀 개발 |