我使用以下代码“非对象字段错误对齐或重叠”错误。
public struct TypeA
{
public string A1;
public string A2;
}
public struct TypeB
{
public string B1,
public string B2;
}
我使用 System.Runtime.InteropServices 与 LayoutKind.Explicit
一起实施 union[StructLayout(LayoutKind.Explicit)]
public struct TypeAorB
{
[FieldOffset(0)]
public TypeA aa;
[FieldOffset(0)]
public TypeB bb;
}
我认为问题来自 struct 中的 string 。我该如何克服这个问题?
答案 0 :(得分:2)
你要做的不合法。 String是引用类型,不能与union中的任何其他内容重叠。它对垃圾收集器来说很重要,它无法可靠地找出存储在字段中的引用,因此如果字符串对象需要保持活动状态,它就无法可靠地判断出来。
关于结构的奇怪之处在于,您将字符串与字符串重叠。哪个在技术上有效,没有理由让垃圾收集器混淆,因为它总是看到有效的对象引用。但它实际上并没有处理这种特殊情况,微软没有编写足够的代码,也没有关心烧掉cpu周期,以检查类型标识。
这是有充分理由的,因为你不必在你的声明中重叠它们。当你可以轻易地避免重叠时,微软没有必要编写特殊代码来识别重叠。
在你的例子中,乌龟一直是下来的,联盟的每个字段是相同的。所以使用联合没有任何意义。
所以不要。
答案 1 :(得分: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;
}