C#中结构的初始化?
我正在修改的一些代码广泛使用结构,通过将它们加载到字节数组或从字节数组加载它们来与一些工厂设备通信 这里有一个这样一个结构的超简化示例C#中结构的初始化?,c#,C#,我正在修改的一些代码广泛使用结构,通过将它们加载到字节数组或从字节数组加载它们来与一些工厂设备通信 这里有一个这样一个结构的超简化示例 [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct K_FOO { public byte a_byte; // 1 byte public BYTE3_TYPE b3; // 3 bytes public int num; // happens
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct K_FOO
{
public byte a_byte; // 1 byte
public BYTE3_TYPE b3; // 3 bytes
public int num; // happens to be 4 bytes
}
字节3_类型看起来像这样
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class BYTE3_TYPE
{
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] L = new byte[3];
}
如果我只是做一个
K_FOO origFoo = new K_FOO();
int和字节被初始化为0,我假设是因为它们是本机类型,但是字节数组b3是*未*初始化的-所有为空。我必须显式地加载它,例如
BYTE3_TYPE b3 = new BYTE3_TYPE();
origFoo.b3 = b3;
。。。我想不出任何替代方案,因为结构不接受无参数构造函数,但真正的结构是巨大的
但我注意到了一些有趣的事情。我们有一些例程可以将这些结构复制到字节数组,也可以从字节数组复制这些结构。例如
public static T ByteArrayToStructure<T>(byte[] buffer) where T : struct
{
int length = buffer.Length;
IntPtr ptr = Marshal.AllocHGlobal(length); // allocate (length) bytes
Marshal.Copy(buffer, 0, ptr, length); // copies into UNmanaged space
T result = (T)Marshal.PtrToStructure(ptr, typeof(T));
Marshal.FreeHGlobal(ptr);
return result;
}
公共静态T ByteArrayToStructure(字节[]缓冲区),其中T:struct
{
int length=buffer.length;
IntPtr ptr=Marshal.AllocHGlobal(长度);//分配(长度)字节
Marshal.Copy(缓冲区,0,ptr,长度);//复制到非托管空间
T result=(T)Marshal.PtrToStructure(ptr,typeof(T));
弗里赫全球元帅(ptr);
返回结果;
}
…如果我叫它
K_FOO retFoo = ByteArrayToStructure<K_FOO>(buffer.bytes);
K_FOO retFoo=ByteArrayToStructure(buffer.bytes);
。。。生成的结构返回完全初始化,字节数组中的字节都分配了空间,以便可以加载,显然是在PtrToStructure()调用中。这意味着.Net“知道”如何初始化这样的结构。那么,有没有办法让.Net帮我做到这一点,这样我就可以避免编写数百行显式初始化代码?提前谢谢 如果将
BYTE3\u类型
设置为结构而不是类,则默认构造函数(调用K\u FOO origFoo=new K\u FOO();
)将正确地将整个内容初始化为零
如果您试图匹配现有规范并将其传递给自定义硬件,这也可能是正确的方法。+1,您可能还想研究一下,这意味着字节数组将嵌入字节3_类型结构中,而不是生活在堆中。我不必设置“不安全”来进行修复吗?现在我有一些例程,比如使用不安全代码的ByteArrayToStructure,但我想让整个程序“安全”,可以这么说。@Reed-我只是用BYTE3_类型作为一个简单的例子-真正的用户定义类型比简单的本机类型数组(如字节)更复杂。我的问题的真正要点是,既然.Net似乎知道如何初始化这些东西,有没有比自己显式地初始化更好的方法呢?@user316117 Fixed确实需要不安全的。您可能希望显式地初始化它。如果不使用非默认构造函数,我通常会创建一个方法来实现这一点。