2025. 7. 5. 12:43ㆍC#
공부 자료 : Pro C# 10 with .NET6
프로그래머가 C# 코드를 빌드하면 CIL 코드로 변환된 .dll 파일이 만들어진다.
이 .dll의 CIL 코드들은 실행 시 JIT 컴파일러에 의해 플랫폼 특화 기계어로 변환되어 명령어가 실행되는 구조이다.
CIL 코드들을 assembly라고 하는데 이 assembly에는 다양한 데이터들이 들어있다. Type Metadata, Manifest 등의 정보들이 있다.
그 중 Type Metadata에는 C# 코드에서 사용된 타입들의 명세가 들어 있다.
이 데이터는 리플랙션, 디버깅 툴, 인텔리센스로 활용되는 중요한 데이터이다.
C#에서 type은 일반적으로 다음과 같다.
Class | 참조 타입. 상태(필드)와 동작(메서드)을 가짐 |
Interface | 동작의 계약만 정의. 구현은 없음 |
Structure | 값 타입. 작은 데이터를 다룰 때 유용 |
Enumeration | 열거형. 미리 정의된 상수 집합 |
Delegate | 메서드를 참조할 수 있는 타입 (콜백 구현 시 사용) |
.NET을 사용하는 모든 프로그래머들은 자신이 사용하는 언어가 CTS의 각 타입들을 어떻게 다루는지 알아야 한다.
CTS Class Types
Class는 OOP의 핵심 개념이다.
아래는 간단한 클래스와 관련된 특성이다.
클래스가 봉인(sealed)되어 있는가? | 봉인된 클래스는 다른 클래스가 이를 상속할 수 없습니다. 즉, 이 클래스는 기반 클래스(base class)로 사용할 수 없습니다. |
클래스가 어떤 인터페이스를 구현하고 있는가? | 인터페이스는 추상 멤버들의 집합이며, 객체와 이를 사용하는 코드 간의 계약(약속)을 제공합니다. CTS에서는 하나의 클래스가 여러 인터페이스를 구현할 수 있습니다. |
클래스가 추상 클래스인가? 구체 클래스인가? |
추상 클래스(abstract class)는 직접 인스턴스를 생성할 수 없으며, 보통 파생 클래스(자식 클래스)에게 공통 동작을 정의하는 데 사용됩니다. 반면, 구체 클래스(concrete class)는 직접 인스턴스를 생성할 수 있습니다. |
이 클래스의 가시성은 어떤가? | 모든 클래스는 반드시 public, internal 등의 가시성 키워드로 설정되어야 합니다. 이 설정은 클래스가 외부 어셈블리에서도 사용 가능한지, 아니면 해당 어셈블리 내에서만 사용 가능한지를 결정합니다. |
CTS Interface Types
인터페이스(Interface)는 단순히 추상 멤버 정의들의 이름 있는 모음이며,
(C# 8부터는) 기본 구현(default implementation)을 포함할 수도 있습니다.
이러한 멤버들은 주어진 클래스나 구조체가 구현하게 되며, 기본 구현의 경우에는 구현 여부가 선택적(optional)입니다.
C#에서는 interface 키워드를 사용하여 인터페이스 타입을 정의합니다.
.NET의 관례상, 모든 인터페이스 이름은 대문자 I로 시작합니다.
인터페이스는 그 자체만으로는 쓸모가 거의 없습니다.
하지만 클래스나 구조체가 특정 인터페이스를 자신만의 방식으로 구현하게 되면,
우리는 그 기능을 다형적인 방식(polymorphic manner)으로 인터페이스 참조를 통해 접근할 수 있습니다.
CTS Structure Types
구조체(structure) 개념도 CTS(Common Type System)에 따라 정의되어 있습니다.
C 언어 배경이 있는 사람이라면, .NET에서도 이러한 사용자 정의 타입(UDT, User Defined Types)이 살아 있다는 점이 반가울 것입니다
(비록 내부 동작은 조금 다르긴 하지만요).
간단히 말해, 구조체는 값 기반의 의미(semantics)를 가지는 가벼운 클래스 타입으로 생각할 수 있습니다.
일반적으로 구조체는 기하학적(geometric) 또는 수학적 데이터 모델링에 가장 잘 어울립니다.
CTS Enumeration Types
열거형(enumeration)은 이름-값 쌍(name-value pair)을 그룹으로 묶는 데 유용한 프로그래밍 구조입니다.
예를 들어, 비디오 게임에서 플레이어가 마법사(Wizard), 전사(Fighter), 도둑(Thief) 중에서 캐릭터를 선택할 수 있다고 가정해 봅시다.
각 캐릭터를 숫자로 구분하는 대신, 강하게 타입화된 열거형을 enum 키워드로 만들 수 있습니다
// C# 열거형 타입 예시
enum CharacterTypeEnum
{
Wizard = 100,
Fighter = 200,
Thief = 300
}
기본적으로, 각 항목을 저장하는 데 사용되는 공간은 32비트 정수(int)입니다.
하지만 저용량 디바이스(예: 모바일)를 위한 프로그래밍에서는 이 저장 공간 크기를 조정할 수도 있습니다.
또한, CTS는 모든 열거형 타입이 공통 기본 클래스인 System.Enum을 상속하도록 요구합니다.
이 기본 클래스는 열거형의 이름-값 쌍을 코드에서 추출, 조작, 변환할 수 있는 다양한 기능을 제공합니다.
CTS Delegate Types
대리자(delegate)는 .NET에서의 타입 안전한(type-safe) C 스타일 함수 포인터에 해당하는 개념입니다.
하지만 중요한 차이점이 있습니다:
C 언어에서는 단순히 메모리 주소를 가리키는 함수 포인터를 사용하지만,
.NET에서는 대리자가 System.MulticastDelegate 클래스를 상속받는 실제 클래스입니다.
C#에서는 delegate 키워드를 사용하여 대리자를 선언합니다.
delegate int BinaryOp(int x, int y)
대리자는 한 객체가 호출을 다른 객체로 전달할 수 있도록 해주는 메커니즘이며, .NET 이벤트 구조의 핵심 기반이 됩니다.
대리자는 멀티캐스팅(multicasting) (즉, 하나의 요청을 여러 수신자에게 전달하는 기능)과 비동기 메서드 호출(즉, 보조 스레드에서 메서드를 실행하는 기능)을 기본적으로 지원합니다.
CTS Type Members
이제 CTS가 정의하는 각 타입(클래스, 인터페이스 등)을 살펴보았으니,
대부분의 타입이 여러 개의 구성 멤버(member)를 가질 수 있다는 점을 이해해야 합니다.
정식으로 말하면, 타입 멤버는 다음 중 하나일 수 있습니다:
생성자(constructor), 소멸자(finalizer), 정적 생성자(static constructor), 중첩 타입(nested type), 연산자(operator), 메서드(method), 속성(property), 인덱서(indexer), 필드(field), 읽기 전용 필드(read-only field), 상수(constant), 이벤트(event)
CTS는 각 멤버에 부여할 수 있는 다양한 속성도 정의합니다.
예를 들어:
- 모든 멤버는 public, private, protected와 같은 가시성(visibility)을 가집니다.
- 어떤 멤버는 추상(abstract)으로 선언되어 파생 타입에서 반드시 구현되도록 강제할 수도 있습니다.
- 또 다른 멤버는 가상(virtual)로 선언되어 기본 구현을 제공하면서도 오버라이드(override)가 가능하도록 할 수 있습니다.
- 대부분의 멤버는 static(클래스 수준) 또는 instance(객체 수준)로 구성될 수 있습니다.
이러한 타입 멤버 생성에 대한 구체적인 내용은 다음 장들에서 다루게 됩니다.
💡 참고:
C# 언어는 제네릭(generic) 타입 및 제네릭 멤버의 생성도 지원합니다.
CTS의 내장 데이터 타입 (Intrinsic CTS Data Types)
CTS의 마지막 주요 요소는 기본 데이터 타입 집합을 명확히 정의한다는 점입니다.
각 .NET 언어(C#, VB.NET 등)는 자신만의 키워드로 기본 타입을 선언하지만, 결국에는 이 모든 키워드가 .NET의 공통 어셈블리(mscorlib.dll) 내에 정의된 동일한 CTS 타입으로 변환(resolve)됩니다.
예를 들어, int, System.Int32, VB.NET의 Integer는 모두 같은 CTS 타입을 가리킵니다.
다음 표에서 확인 할 수 있습니다.
CTS Data Type | VB Keyword | C# Keyword |
System.Byte | Byte | byte |
System.SByte | SByte | sbyte |
System.Int16 | Short | short |
System.Int32 | Integer | int |
System.Int64 | Long | long |
System.UInt16 | UShort | ushort |
System.UInt32 | UInteger | uint |
System.UInt64 | ULong | ulong |
System.Single | Single | float |
System.Double | Double | double |
System.Object | Object | object |
System.Char | Char | char |
System.String | String | string |
System.Decimal | Decimal | decimal |
System.Boolean | Boolean | bool |
'C#' 카테고리의 다른 글
Thread (2) | 2025.07.27 |
---|---|
C#의 Structure 타입 (0) | 2025.07.07 |
[C# 9] top-level statements (0) | 2025.07.05 |
[C# 10] File Scoped Namespaces (0) | 2025.07.05 |
C#과 .NET 6에 대한 기초 개념 (0) | 2025.07.05 |