는 I는 구조체의 단독 표현에 영향 documentation for [FieldOffset] 따르면 C 번호.NET의 통합 필드 - 실제로 관리되는 코드에서 작동 할 수 있습니까?
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)]
public string MyString;
[FieldOffset(0)]
public Version MyVersion;
}
이 같은 구조체를 정의. 그러나 놀랍게도 관리되는 코드에서 제대로 작동하는 것 같습니다. dotTrace에서 메모리 사용량을 프로파일 링 할 때 각 MyUnion
인스턴스는 하나의 포인터 크기 (x64의 경우 8 바이트)입니다! 값은 여전히 완벽하게 안전합니다.
var stringInside = new MyUnion { MyString = "The string" };
var versionInside = new MyUnion { MyVersion = new Version(1, 2, 3, 4) };
Console.WriteLine(stringInside.MyString); // The string
Console.WriteLine(versionInside.MyVersion); // 1.2.3.4
하지만 잘못된 필드에 액세스하면 어떻게됩니까?
var whatIsThis = stringInside.MyVersion;
var andThis = versionInside.MyString;
Console.WriteLine("{0} (type = {1})", whatIsThis, whatIsThis.GetType().FullName); // The string (type = System.String)
Console.WriteLine("{0} (type = {1})", andThis, andThis.GetType().FullName); // 1.2.3.4 (type = System.Version)
포함 된 객체의 실제 타입이 보존하지만, 물론 지금은 어떤 컴파일러가 생각하는 어떤 런타임이 생각하는, 예를 들어, 사이에 분리가되어 있다는 의미에서이 여전히 "작품"
Console.WriteLine("Compiler: is it a string? {0}", versionInside.MyString is string); // True
Console.WriteLine("Runtime: is it a version? {0}", versionInside.MyString.GetType() == typeof(Version)); // True
이렇게 노조를 사용하는 것은 얼마나 위험합니까? 내가 여기있는 행동에 의지 할 수 있을까요? 다른 방법으로 부서지기 쉬운가요? 특히 이런 코드를 사용하는 것이 안전할까요?
if (versionInside.MyString.GetType() == typeof(string))
{
Console.WriteLine("OK, it's a string, use the MyString field");
}
else
{
Console.WriteLine("OK, it's a Version, use the MyVersion field");
}
노동 조합의 목적은 전통적으로 메모리를 절약하는 것입니다. 실제로 이것은 여전히 문제입니까? 오늘날 복잡성/난독 화 가치가 있습니까? –
예, 물론입니다. 데이터가 충분하면 메모리가 항상 문제가됩니다. – EM0
잘 문서화하십시오. - 어쨌든 50 세 이하의 개발자들과 함께 놀랍게도 몇 명의 개발자를 만나게 될 것입니다. –