C 또는 C++ 언어에서는 공용체라는 것이 있습니다
구조체와 유사하지만, 메모리 할당 측면이 조금 다르죠
C 문법으로,
구조체는 struce , 공용체는 union 키워드를 사용하여 정의합니다
구조체는 멤버들의 타입에 따라 메모리 공간이 각각 할당되지만,
공용체는 멤버들이 메모리 공간을 공용으로 사용하게 됩니다
아래 구조체의 경우 int 타입의 멤버가 2개 정의되어 있습니다
int 는 4byte 메모리 공간을 차지하기에 i, j 모두 각각 메모리를 할당받게 되어 총 8byte 의 크기를 가지게 됩니다
//구조체 정의
struct MyStruct1
{
public int i;
public double j;
}
//구조체 크기
System.Runtime.InteropServices.Marshal.SizeOf(typeof(MyStruct1)); // 8 반환
그러나 공용체의 경우는 다릅니다
C에서는 union 을 통해 공용체를 정의할 수 있지만, C#에서는 특별히 공용체라는 타입이 존재하지는 않습니다
다만 구조체의 멤버들의 레이아웃을 명시적으로 지정할 수 있도록 하는데, 이 방식을 이용해 공용체를 정의할 수
있습니다.
닷넷 프레임웍의 StructLayoutAttribute 특성을 이용하면 구조체 멤버들의 레이아웃을 제어할 수 있습니다
보통 StructLayoutAttribute 특성은 닷넷에서 C++과 같은 비관리코드에 구조체를 전송할 경우 많이 사용하게 됩니다
다음 코드는 구조체를 공용체로 만드는 코드 입니다
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
struct MyStruct2
{
[System.Runtime.InteropServices.FieldOffset(0)]
public int i;
[System.Runtime.InteropServices.FieldOffset(0)]
public int j;
}
LayoutKind.Explicit 를 지정하여 구조체의 각 멤버들의 위치를 명시적으로 제어하도록 하며,
i 와 j 의 시작 위치를 둘다 0으로 지정하면, 같은 메모리 영역을 사용하게 됩니다(즉 공용체이죠)
이렇게 정의된 구조체(공용체)의 사이즈(size)를 아래의 코드로 확인하면 4 byte 임을 알 수 있습니다
System.Runtime.InteropServices.Marshal.SizeOf(typeof(MyStruct2)); // 4 반환
즉, int 타입 멤버 i, j 가 4byte 메모리 공간을 공유하게 되는 것입니다
만일 j 가 double 타입이라면, 공용체의 크기는 8byte 가 됩니다. 다시말해 공용체의 경우 멤버들 중 가장 큰 타입의 크기가 할당되게 됩니다
메모리가 공유되는 것을 확인하기 위해 다음의 코드를 확인해 보세요
MyStruct2 myStruct2 = new MyStruct2();
myStruct2.i = 10;
myStruct2.j = 20;
Console.WriteLine(myStruct2.i); // i 의 값이 무엇일까요?
분명 i 에 10을 지정했지만 결과는 20입니다. 즉 나중에 할당된 j 값이 i 의 값을 덮어 써버리게 된 것입니다
다만, 여기서 중요한 것은 i 값이 20이라는 것이 아니라, 메모리가 공유된다는 것이며 공유된 상태에서 다른 값은
무의미하다는 것입니다. 실제로 예제에서, j 의 타입이 double 였다면 i 값은 20이 아니라 0 이 됩니다.
즉 덮어쓰진 멤버값은 참조할 가치가 없는 쓰레기 값이라고 생각하면 됩니다