【问题标题】:Initialization of a struct in C#?在 C# 中初始化结构?
【发布时间】:2013-02-04 17:06:41
【问题描述】:

我正在修改的一些代码广泛使用结构来与某些工厂设备进行通信,方法是将它们加载到字节数组或从字节数组加载。

这是一个这样的结构的超级简化示例。

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

BYTE3_TYPE 看起来像这样...

[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 和 byte 被初始化为 0,我假设是因为它们是原生类型,但字节数组 b3 是 *un*initialized - 全部为空。我必须显式加载它,例如,

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

...如果我称它为...

    K_FOO retFoo = ByteArrayToStructure<K_FOO>(buffer.bytes);

...返回的结果结构完全初始化,字节数组中的字节都已分配空间,因此可以加载它们,显然是在 PtrToStructure() 调用中。这意味着.Net“知道”如何初始化这样的结构。那么有没有办法让 .Net 为我做到这一点,这样我就可以避免编写数百行显式初始化代码?提前致谢!

【问题讨论】:

    标签: c#


    【解决方案1】:

    如果您将BYTE3_TYPE 设为结构而不是类,则默认构造函数(调用K_FOO origFoo = new K_FOO();)会将整个事物正确初始化为零。

    如果您尝试匹配现有规范并将其传递给自定义硬件,这也可能是正确的方法。

    【讨论】:

    • +1,你也可以看看fixed size buffers,这意味着字节数组将嵌入到 BYTE3_TYPE 结构中,而不是在堆上。
    • 我不是必须设置不安全才能修复吗?现在我有一些例程,比如使用不安全代码的 ByteArrayToStructure,但我想保持整个程序“安全”,可以这么说。
    • @Reed - 我只是用 BYTE3_TYPE 作为一个简单的例子 - 真正的用户定义类型比简单的原生类型数组(如字节)更复杂。我的问题的真正要点是,由于 .Net 似乎知道如何初始化这些东西,有没有比我自己明确地做更好的方法来做到这一点?
    • @user316117 固定确实需要不安全。您可能希望显式初始化它。如果您不使用非默认构造函数,我经常会创建一个方法来执行此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多