2014-02-10 43 views
0

我有「錯誤地對齊或重疊非對象字段錯誤與下面的代碼。C#中的聯合字符串錯誤對齊

public struct TypeA 
{ 
    public string A1; 
    public string A2; 
} 
public struct TypeB 
{ 
    public string B1, 
    public string B2; 
} 

我實現工會使用System.Runtime.InteropServicesLayoutKind.Explicit

[StructLayout(LayoutKind.Explicit)] 
public struct TypeAorB 
{ 
    [FieldOffset(0)] 
    public TypeA aa; 

    [FieldOffset(0)] 
    public TypeB bb; 
} 

我認爲這個問題在結構來自字符串。我如何克服這個問題?

+0

我認爲託管(非標量)類型的別名可能不被允許。 –

+0

你想通過這樣做來達到什麼目的? –

+0

謝謝你們,我想要做的是實現維護超級* struct *包含多個* struct *(s)。它試圖從C代碼中實現* union *。現在我明白*引用類型*不能重疊。 – sMah

回答

2

你正在嘗試做的是不合法。字符串是參考類型,不能與聯合中的其他任何內容重疊。它對垃圾收集器很重要,它不能可靠地弄清楚在一個字段中存儲了什麼引用,所以如果字符串對象需要保持活動狀態,它不能可靠地弄清楚。

什麼是你的結構bizarro是你重疊字符串的字符串。這在技術上是可行的,因爲垃圾收集器總是看到一個有效的對象引用,所以它沒有理由被混淆。但它實際上並沒有處理這種特殊情況,微軟沒有編寫足夠的代碼,或者關心刻錄CPU週期來檢查類型標識。

而這是一個很好的理由,因爲不必在你的聲明中重疊它們。當你可以輕易地避免重疊時,微軟沒有必要編寫特殊代碼來識別重疊。

在你的例子中一直是龜,聯合領域是相同的。所以在使用工會方面沒有任何意義。

所以不要。

+0

感謝您的回覆和解釋。 – sMah

0

爲什麼fieldoffsets是相同的?它們應該是0和0+ [TypeA的大小]。

類型A是8個字節,因爲您有2個字符串,每個字符將使用4個字節的指針。

因此...

[StructLayout(LayoutKind.Explicit)] 
    public struct TypeAorB 
    { 
     [FieldOffset(0)] 
     public TypeA aa; 

     [FieldOffset(8)] 
     public TypeB bb; 
    } 

如果您要再次添加的TypeB的第三場,你需要做的:

[StructLayout(LayoutKind.Explicit)] 
    public struct TypeAorB 
    { 
     [FieldOffset(0)] 
     public TypeA aa; 

     [FieldOffset(8)] 
     public TypeB bb; 

     [FieldOffset(16)] 
     public TypeB bb; 
    } 
+0

謝謝喬恩,這是有用的信息。 – sMah

+0

因爲他正在嘗試創建一個聯盟。 –