1

次のコードを使用すると、 「オブジェクト以外のフィールドが正しく配置されていないか、重なり合っています」というエラーが発生します。

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;
}

問題はstructのstringにあると思います。この問題を解決するにはどうすればよいですか?

4

2 に答える 2

2

あなたがやろうとしていることは合法ではありません。文字列は参照型であり、共用体で他のものと重複することはできません。これはガベージ コレクターにとって非常に重要です。どの参照がフィールドに格納されているかを確実に把握できないため、文字列オブジェクトを維持する必要があるかどうかを確実に判断できません。

構造体の奇妙な点は、文字列と文字列を重ねていることです。ガベージ コレクターは常に有効なオブジェクト参照を参照するため、ガベージ コレクターが混乱する理由はありません。しかし、それは実際にはその特殊なケースを処理しません.Microsoftは十分なコードを書いていないか、型の同一性をチェックするためにCPUサイクルを燃やしていませんでした.

宣言でそれらをオーバーラップする必要がないため、これには正当な理由があります。オーバーラップを簡単に回避できる場合に、Microsoft がオーバーラップを認識するための特別なコードを作成しても意味がありません。

そして、あなたの例ではタートルがずっと下にあり、ユニオンのすべてのフィールドは同一です。したがって、ユニオンを使用しても意味がありません。

だからしないでください。

于 2014-02-10T23:38:17.683 に答える
-2

Why are the fieldoffsets the same? They should be 0 and 0+[size of TypeA].

Type A is 8 bytes as you have 2x strings, and each one will use a 4 byte pointer.

Therefore...

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

        [FieldOffset(8)]
        public TypeB bb;
    }

If you were to add a third field of typeB again, you'd need to do:

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

        [FieldOffset(8)]
        public TypeB bb;

        [FieldOffset(16)]
        public TypeB bb;
    }
于 2014-02-10T23:24:02.957 に答える