C#에서의 구조체(struct)
구조체(Struct)란, 연관된 여러 데이터를 하나의 단위로 묶어 처리하기 위해 사용되는 구조화 된 데이터입니다.
C#에서의 구조체는 값 타입(value type)이며, 기본적으로 데이터 그룹을 관리하기 위해 사용됩니다.
구조체 정의 및 선언
구조체는 struct
키워드를 사용하여 정의합니다.
이때, 각 멤버의 기본 접근 지정자는 internal
인데, 어셈블리 외부에서도 접근 가능하도록 하려면 public
접근 지정자를 명시적으로 사용해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
public void Move(int dx, int dy)
{
X += dx;
Y += dy;
}
public override string ToString()
{
return $"({X}, {Y})";
}
}
구조체의 특징
- 값 타입(Value Type)
- 구조체는 값 타입으로, 스택에 할당됩니다. 이는 구조체 인스턴스가 복사될 때 새로운 인스턴스가 만들어 진다는 것을 의미합니다.
- 단, 컴파일러와 CLR의 최적화에 따라 힙에 할당 될 수도 있습니다. 예를 들어, 클래스의 필드로 선언된 구조체는 해당 클래스 객체와 함께 힙에 저장됩니다.
- 초기화
- 구조체는 기본적으로 초기화되지 않은 상태로 생성됩니다. 따라서 구조체의 각 필드는 생성자에서 명시적으로 초기화해야 합니다.
- 생성자
- 구조체는 매개변수를 가지는 생성자를 가질 수 있지만, 생성자 내에서 구조체의 모든 필드를 반드시 초기화해야 합니다.
- C# 9.0 이하에서는 기본 생성자(매개변수가 없는 생성자)는 만들 수 없습니다.
- 상속
- 구조체는 다른 구조체나 클래스로부터 상속받을 수 없습니다. 단, 인터페이스는 구현할 수 있습니다.
- 박싱 및 언박싱(Boxing and Unboxing)
- 구조체는
object
타입이나 인터페이스 타입으로 변환될 때 박싱(Boxing)이 일어나며, 이는 힙에 객체를 생성하는 작업입니다. 박싱된 구조체를 다시 값 타입으로 변환하는 과정을 언박싱(Unboxing)이라 합니다. - 이 과정에서 오버헤드(Overhead)가 일어날 수 있으며, 성능 저하가 발생할 수 있습니다.
- 구조체는
구조체 사용 예시
1
2
3
4
5
6
7
Point p1 = new Point(10, 20);
Point p2 = p1; // 값 복사
p2.Move(5, 5);
Console.WriteLine(p1); // 출력: (10, 20)
Console.WriteLine(p2); // 출력: (15, 25)
위 예시는 구조체가 값 타입이고, 기본적으로는 복사가 일어난다는 것을 보여주는 예시입니다.
p1
구조체를 생성하고, p2
에 p1
구조체를 넣었지만, p1
과 p2
는 각각 독립적인 인스턴스입니다. p2
를 변경해도 p1
에는 영향을 미치지 않습니다.
구조체와 클래스의 비교
- 메모리 할당: 구조체는 스택에 할당되며, 클래스는 힙에 할당됩니다.
- 참조 타입 vs 값 타입: 클래스는 참조 타입으로, 동일 객체를 여러 참조가 가리킬 수 있습니다. 반면, 구조체는 값 타입으로, 복사된 인스턴스는 독립적입니다.
- 성능: 성능 측면에서, 구조체는 작은 데이터 구조를 다룰 때 빠른 복사와 높은 캐시 효율성으로 인해 유리할 수 있습니다. 반면, 크고 복잡한 데이터 구조에서는 클래스를 사용하는 것이 더 효율적일 수 있습니다.
참고
이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.