C# 在C中为结构创建字节数组成员#

C# 在C中为结构创建字节数组成员#,c#,structure,C#,Structure,我的结构定义如下: public struct check { public int[] x = new int[3]; //error } 这是一个错误,因为无法在C#中定义结构成员的数组大小。即使在C#中的默认构造函数中,我也无法定义此数组的空间,因为不允许使用无参数构造函数 我该怎么做?我知道结构在C#中是不可变的 我使用这个结构不是为了创建新对象,而是为了类型转换其他类类型的对象 check corp = (check )WmUtils.WM_GetObj(Attr); Wm

我的结构定义如下:

public struct check
{
    public int[] x = new int[3]; //error
}
这是一个错误,因为无法在C#中定义结构成员的数组大小。即使在C#中的默认构造函数中,我也无法定义此数组的空间,因为不允许使用无参数构造函数

我该怎么做?我知道结构在C#中是不可变的

我使用这个结构不是为了创建新对象,而是为了类型转换其他类类型的对象

check corp = (check )WmUtils.WM_GetObj(Attr);

Wm_getObj返回check2类类型的对象。readonly关键字在这里有用吗?

您不能使用无参数构造函数,也不能在struct中定义大小为的数组,这会使结构构造函数将
大小作为参数,如:

public struct check
{
    public int[] x;
    public check(int size)
    {
        x = new int[size];
    }
}
给定check2类:

  public class check2
  {
     public int x1 { get; set; }
     public int x2 { get; set; }
     public int x3 { get; set; }
  }
在具有整数数组的结构中,只需添加一个运算符即可从类中强制转换它。操作员可以从类实例初始化数组:

  public struct check
  {
     public int[] x;

     public static explicit operator check(check2 c2)
     {
        return new check() { x = new int[3] { c2.x1, c2.x2, c2.x3 } };
     }
  }
现在,您可以创建一个
check2
类并将其强制转换为
check
结构:

  check2 c2 = new check2() { x1 = 1, x2 = 2, x3 = 3 };
  check s = (check)c2;
  Console.WriteLine(string.Format("{0}, {1}, {2}", s.x[0], s.x[1], s.x[2]));
这将输出
1、2、3

一个:

公共不安全结构缓冲区
{
常数int Size=100;
固定字节数据[大小];
公共空间清除()
{
固定(字节*ptr=数据)
{
//用0填充值

对于(int i=0;i使用类而不是结构。

这样如何:

struct Check
{
  private int[] _x ;
  public int[] X { get { return _x ?? new int[3]{0,0,0,} ; } }
}

这会延迟内部数组的实例化,直到它被引用。可能数组引用在实例的整个生命周期内保持不变,因此您实际上不需要
访问器。这里唯一的真正缺点是,由于对属性的第一次引用的隐式争用条件,这不是线程安全的
X
。但是,由于您的结构假定位于堆栈上,因此这似乎不是一个大问题。

这可能会有很大帮助。我创建了结构MyX, Struct包含ToByte和tostruct方法 所以,如果你有字节数组,你可以用字节填充你的结构数组 但请确保字节数组对齐方式是正确的。 希望这有帮助

    public struct MyX
    {
        public int IntValue;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U1)]
        public byte[] Array;

        MyX(int i, int b)
        {
            IntValue = b;
            Array = new byte[3];
        }

        public MyX ToStruct(byte []ar)
        {

            byte[] data = ar;//= { 1, 0, 0, 0, 9, 8, 7 }; // IntValue = 1, Array = {9,8,7}
            IntPtr ptPoit = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, ptPoit, data.Length);

            MyX x = (MyX)Marshal.PtrToStructure(ptPoit, typeof(MyX));
            Marshal.FreeHGlobal(ptPoit);

            return x;
        }
        public byte[] ToBytes()
        {
            Byte[] bytes = new Byte[Marshal.SizeOf(typeof(MyX))];
            GCHandle pinStructure = GCHandle.Alloc(this, GCHandleType.Pinned);
            try
            {
                Marshal.Copy(pinStructure.AddrOfPinnedObject(), bytes, 0, bytes.Length);
                return bytes;
            }
            finally
            {
                pinStructure.Free();
            }
        }
    }

    void function()
    {
        byte[] data = { 1, 0, 0, 0, 9, 8, 7 }; // IntValue = 1, Array = {9,8,7}
        IntPtr ptPoit = Marshal.AllocHGlobal(data.Length);
        Marshal.Copy(data, 0, ptPoit, data.Length);

        var x = (MyX)Marshal.PtrToStructure(ptPoit, typeof(MyX));
        Marshal.FreeHGlobal(ptPoit);

        var MYstruc = x.ToStruct(data);


        Console.WriteLine("x.IntValue = {0}", x.IntValue);
        Console.WriteLine("x.Array = ({0}, {1}, {2})", x.Array[0], x.Array[1], x.Array[2]);
    }

这确实有效,我知道,但我不希望在创建对象时传递大小,因为大小始终固定为3。如果大小始终为3,为什么不创建3个int变量?如果大小为100?@tylerduden,为什么不使用
而不是
结构
?你说这是可行的,但它是如何从c初始化的lass?不是。它只是创建一个默认值的int数组。实际上它并不总是check2 typecasted,有时其他结构你需要为它们中的每一个定义一个操作符。它们之间可能有一些共享代码,但最终每个转换都必须被定义。它的吠叫多于它的叮咬。当正确完成时,它是完全安全的e、 简单一点。我讨厌他们用“不安全”这个词来形容“应该是遗留的”或“允许指针”。你是对的!这实际上是我的思维障碍,它意味着一个绝妙的答案。在泰勒·德登(Tyler Durden)中,我们相信!但如果你想强制转换,你仍然需要定义运算符!结构在C#中不是天生不变的。这只是一个真正的问题让它们可变是个坏主意,因为它会导致各种各样的问题。
    public struct MyX
    {
        public int IntValue;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U1)]
        public byte[] Array;

        MyX(int i, int b)
        {
            IntValue = b;
            Array = new byte[3];
        }

        public MyX ToStruct(byte []ar)
        {

            byte[] data = ar;//= { 1, 0, 0, 0, 9, 8, 7 }; // IntValue = 1, Array = {9,8,7}
            IntPtr ptPoit = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, ptPoit, data.Length);

            MyX x = (MyX)Marshal.PtrToStructure(ptPoit, typeof(MyX));
            Marshal.FreeHGlobal(ptPoit);

            return x;
        }
        public byte[] ToBytes()
        {
            Byte[] bytes = new Byte[Marshal.SizeOf(typeof(MyX))];
            GCHandle pinStructure = GCHandle.Alloc(this, GCHandleType.Pinned);
            try
            {
                Marshal.Copy(pinStructure.AddrOfPinnedObject(), bytes, 0, bytes.Length);
                return bytes;
            }
            finally
            {
                pinStructure.Free();
            }
        }
    }

    void function()
    {
        byte[] data = { 1, 0, 0, 0, 9, 8, 7 }; // IntValue = 1, Array = {9,8,7}
        IntPtr ptPoit = Marshal.AllocHGlobal(data.Length);
        Marshal.Copy(data, 0, ptPoit, data.Length);

        var x = (MyX)Marshal.PtrToStructure(ptPoit, typeof(MyX));
        Marshal.FreeHGlobal(ptPoit);

        var MYstruc = x.ToStruct(data);


        Console.WriteLine("x.IntValue = {0}", x.IntValue);
        Console.WriteLine("x.Array = ({0}, {1}, {2})", x.Array[0], x.Array[1], x.Array[2]);
    }