서론
프로그래밍 언어의 가장 기본이면서도 핵심적인 부분을 차지하는 것이 바로 데이터 타입입니다. 프로그래밍 언어를 배우는 과정에서 데이터 타입의 중요성을 간과하기 쉽지만, 이는 마치 집을 지을 때 기초 공사를 소홀히 하는 것과 같습니다. 특히 C#과 같은 강력한 타입 시스템을 가진 언어에서는 더욱 그렇습니다.
이번 포스트에서는 '이것이 C#이다' 책의 3장 내용을 바탕으로, C#의 데이터 타입에 대해 깊이 있게 살펴보겠습니다. 값 형식과 참조 형식의 차이, 기본 데이터 형식, Nullable 타입, var 키워드, 그리고 공용 형식 시스템(CTS)에 이르기까지, C# 데이터 타입의 핵심을 정리해 보겠습니다.
본론
1. 데이터 타입 개요
C#은 다양한 데이터 타입을 제공하며, 이는 크게 기본 데이터 형식(Primitive Type)과 복합 데이터 형식(Complex Data Type)으로 나눌 수 있습니다. 또한, 모든 데이터 타입은 값 형식(Value Type)과 참조 형식(Reference Type)으로 분류됩니다.
// 기본 데이터 형식 예시
int number = 10; // 값 형식
string text = "Hello"; // 참조 형식
// 복합 데이터 형식 예시
struct Point { public int X, Y; } // 값 형식
class Person { public string Name; public int Age; } // 참조 형식
C#
복사
2. 값 형식과 참조 형식
2.1 값 형식 (Value Types)
값 형식은 변수가 직접 값을 담는 데이터 형식입니다. 대표적으로 정수형(int, long 등), 부동 소수점형(float, double), 구조체(struct) 등이 있습니다. 값 형식 변수는 스택 메모리에 할당됩니다.
int a = 10;
int b = a;
b = 20;
Console.WriteLine($"a: {a}, b: {b}"); // 출력: a: 10, b: 20
C#
복사
위 예제에서 b의 값을 변경해도 a의 값은 영향을 받지 않습니다. 이는 값 형식의 특징입니다.
2.2 참조 형식 (Reference Types)
참조 형식은 변수가 값 대신 메모리 주소를 담는 데이터 형식입니다. 대표적으로 클래스(class), 인터페이스(interface), 배열(array) 등이 있습니다. 참조 형식의 데이터는 힙 메모리에 할당되고, 변수는 그 메모리 주소를 가리킵니다.
class Person
{
public string Name;
}
Person person1 = new Person { Name = "Alice" };
Person person2 = person1;
person2.Name = "Bob";
Console.WriteLine($"person1.Name: {person1.Name}, person2.Name: {person2.Name}");
// 출력: person1.Name: Bob, person2.Name: Bob
C#
복사
여기서 person2를 변경하면 person1도 영향을 받습니다. 두 변수가 같은 객체를 참조하고 있기 때문입니다.
2.3 메모리 관리: 스택과 힙
스택은 함수 호출이 끝나면 자동으로 메모리를 정리합니다. 반면 힙은 가비지 컬렉터(Garbage Collector)가 주기적으로 사용하지 않는 객체를 제거합니다. 이러한 차이로 인해 참조 형식은 값 형식보다 메모리 관리 측면에서 더 복잡하지만, 더 유연한 사용이 가능합니다.
2.4 박싱과 언박싱 (Boxing and Unboxing)
값 형식을 참조 형식으로 변환하는 과정을 박싱(Boxing), 그 반대를 언박싱(Unboxing)이라고 합니다. 이 과정은 성능에 영향을 줄 수 있어 주의가 필요합니다.
int number = 123;
object boxed = number;// 박싱
int unboxed = (int)boxed;// 언박싱
C#
복사
3. 기본 데이터 형식
C#은 15가지의 기본 데이터 형식을 제공하며, 이는 크게 숫자 형식, 논리 형식, 문자열 형식, 오브젝트 형식으로 나눌 수 있습니다.
// 숫자 형식
int integerNumber = 10;
double floatingPointNumber = 3.14;
// 논리 형식
bool isTrue = true;
// 문자열 형식
string greeting = "Hello, World!";
// 오브젝트 형식
object anyData = 42; // 박싱(Boxing)
C#
복사
특히 object 형식은 모든 데이터 형식의 기반이 되는 특별한 형식입니다. 어떤 데이터든 담을 수 있지만, 박싱/언박싱 과정이 필요해 성능 면에서 주의가 필요합니다.
4. Nullable 형식
C#에서는 값 형식에 null을 할당할 수 없습니다. 하지만 때로는 값이 없음을 표현해야 할 때가 있습니다. 이를 위해 C#은 Nullable 형식을 제공합니다.
int? nullableInt = null;
double? nullableDouble = 3.14;
if (nullableInt.HasValue)
{
Console.WriteLine($"Value: {nullableInt.Value}");
}
else
{
Console.WriteLine("No value");
}
C#
복사
Nullable 형식은 데이터베이스 작업이나 사용자 입력 처리 등에서 매우 유용하게 사용됩니다.
5. var 키워드
var 키워드를 사용하면 컴파일러가 변수의 타입을 자동으로 추론합니다. 이는 코드의 가독성을 높이고 작성을 편리하게 만들어 줍니다.
var number = 10; // int로 추론
var text = "Hello"; // string으로 추론
var list = new List<int>(); // List<int>로 추론
C#
복사
단, var를 사용할 때는 초기화가 반드시 필요하며, 지역 변수로만 사용할 수 있다는 제약이 있습니다.
6. 공용 형식 시스템 (CTS)
C#의 형식 시스템은 .NET의 공용 형식 시스템(Common Type System, CTS)을 따릅니다. 이는 .NET 프레임워크에서 지원하는 모든 언어가 공통으로 사용하는 데이터 형식 체계입니다.
System.Int32 a = 123; // CTS 형식명
int b = 456; // C# 키워드
Console.WriteLine(a.GetType() == b.GetType()); // 출력: True
C#
복사
CTS의 존재로 인해 다른 .NET 언어로 작성된 코드와의 상호운용성이 보장됩니다.
결론
C# 데이터 타입을 공부하면서, 다른 언어와는 다른 특이한 문법들이 눈에 띄었습니다. 특히 Nullable 형식과 var 키워드는 C#만의 문법은 아니지만, 유의할만한 특징이라고 할 수 있을 것 같습니다. 이런 문법들은 단순히 편의성을 넘어서 C#의 철학을 보여주는 것 같습니다.
이번 학습을 통해 C#을 제대로 이해하려면 .NET 프레임워크에 대한 이해가 필수적이라는 것을 깨달았습니다. 특히 공용 형식 시스템(CTS)에 대해 알게 되면서, 이전 프로젝트에서 봤던 이상한 타입 표기들이 갑자기 이해가 되는 것 같습니다. System.Int32나 System.String 같은 표기가 왜 사용되는지 이제야 알게 됐습니다.
앞으로는 C# 문법뿐만 아니라 .NET 프레임워크의 구조와 철학에 대해서도 더 깊이 공부해야겠다는 생각이 듭니다.
참고 자료
•
박상현, "이것이 C#이다", 한빛미디어, 2023