2010-07-10 7 views
4

왜 C#에 노동 조합이 없는지에 대한 기술적 인 측면을 이해하려고합니다. 명시 적 구조 레이아웃을 가진 특성 메커니즘을 사용하는 것이 트릭을 이해한다는 것을 이해합니다. 왜 이것이 바닐라 조합 구조보다 선호되는 이유인지에 더 많은 관심이 있습니다.왜 C#에는 공용체가 없습니까?

+0

공용체 SomeUnion {string SomeStringPointer; IntPtr PointerValue; } SomeUnion u; u.PointerValue = 새로운 IntPtr (0x98765432); Console.WriteLine (u.SomeStringPointer); – wj32

+0

@ wj32이 코드가 컴파일됩니까? – Fanatic23

+0

그 설명은 자기 설명 적으로하기위한 것이었다 :) 절대, 나는 적절한 대답을 게시하고있다. – wj32

답변

6

유니온을 허용하면 특히 관리되는 개체와 관련하여 .NET의 안전이 저하 될 수 있습니다.

예를 들어 (32 비트 시스템) :

union MyUnion 
{ 
    string SomeString; // just a 4 byte pointer 
    uint SomeInteger; 
} 

MyUnion u; 

u.SomeInteger = 0x98765432; 
// What's u.SomeString? What happens if I try to access it? 

C#을 당신이 안전하지 않은 키워드로 발에 특정 속성으로 자신을 쏠 수 있지만 결코 관리되는 형식을 포함하지 않습니다. FieldOffset을 사용하면 임의의 유형을 함께 조합 할 수 없습니다. 위의 "조합"으로 시도하십시오.

가 는

유형 'MyUnion을'로드 어셈블리에서 할 수 없습니다 'ConsoleApplication2, 버전 = 1.0.0.0, 문화, 가 PublicKeyToken = null이 중립 ='그것이 객체를 포함하고 있기 때문에 다음은

내가 무엇을 얻을 필드가으로 잘못 정렬되었거나 이 비 개체 필드로 겹쳐져 있습니다.

+0

사실, 명시 적 레이아웃과 겹치는 필드 오프셋을 사용하여 유형 시스템에 혼란을 야기 할 수 있습니다. 런타임은 객체 필드와 객체가 아닌 필드의 잘못된 정렬 또는 겹침에 대한 유형로드 예외를 발생 시키지만 확인을 건너 뛸 수있는 권한이있는 코드는 관리되는 유형에 대한 참조와 겹칠 수 있습니다. IMHO, LayoutKind를 사용하면 불행한 일입니다 .Explicit는 unsafe 할 수있는 코드를 생성 할 수 있기 때문에 안전하지 않은 키워드를 요구하지 않습니다. –

+0

아, 재미 있어요! 나는 그것을 몰랐다. – wj32

4

유니온은 본질적으로 형식에 안전하지 않으며 포인터에 안전하지 않으므로 CLR은 두 가지 모두에 중점을 둡니다.

는 다음과 같은 고려 :

union MyUnion 
{ 
    private List<int> myList; 
    private int integer; 

    public MyUnion(int foo) { integer = foo; } 
    public List<int> List { get { return myList; } } 
} 

이뿐만 아니라이 아주 많이 (특히 64 비트 플랫폼에서) 작동하지 않을 수 있지만, 그것은 또한 읽어 아파요 CLR의 많은 보장을 나누기.

먼저 포인터를 실제로 사용하지 않고 포인터를 가져올 수 있으므로 유니언은 모두 unsafe으로 분류해야합니다. 그런 다음이 포인터를 변경할 수도 있습니다. 예를 들어 우연히 다른 유효한 목록의 주소로 변경하면 가비지 수집기가이 목록을 이동시키고 귀하의 정수없이 말하십시오.

또한 형식이 완전히 안전하지 않습니다. 리스트는 정수와 아무런 관련이 없습니다. 그러나 정수는 포인터처럼 보이기 때문에 "나쁘지 않다". 이제 다음 예제를 고려하십시오

union MyUnion 
{ 
    private List<int> myList; 
    private Form myForm; 

    public MyUnion(Form theForm) { myForm = theForm; } 

    public List<int> List { get { return myList; } } 
} 

이제 MyUnion.List.Add (4)를 호출하는 경우 거 양식으로 할 것이 무엇인가? 분명히, 충돌. 이것은 완전히 유형이 안전하지 않기 때문에,하지만 조합은 안전하다고 믿게합니다.

1

참조 유형을 값 유형으로 만들 수있는 경우 ValueWrapperStructLayout(LayoutKind.Explicit) 속성을 사용할 수 있습니다. 몇 주 전에이 팁을 보았습니다 here.

관련 문제