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

时间:2013-10-25 18:07:51

标签: c# structure

我的结构定义如下:

public struct check
{
    public int[] x = new int[3]; //error
}

这是一个错误,因为您无法在C#中为结构成员定义数组大小。即使在C#中的默认构造函数中,我也无法为此数组定义空间,因为不允许使用无参数构造函数。

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

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

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

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

6 个答案:

答案 0 :(得分:2)

你不能有一个参数较少的构造函数,你不能在struct中定义一个大小的数组,这会留下一个结构构造函数,以size为参数,如:

public struct check
{
    public int[] x;
    public check(int size)
    {
        x = new int[size];
    }
}

答案 1 :(得分:2)

这个怎么样:

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

这会延迟内部数组的实例化,直到被引用为止。据推测,数组引用在实例的生命周期内保持不变,因此您实际上不需要set访问器。这里唯一真正的缺点是,由于第一次引用属性X的隐式竞争条件,这不是线程安全的。但是,由于你的结构假定存在于堆栈中,看起来这可能不是一个大问题。

答案 2 :(得分:1)

给出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

答案 3 :(得分:1)

fixed array buffer

怎么样?
public unsafe struct Buffer
{
    const int Size=100;
    fixed byte data[Size];

    public void Clear()
    {
        fixed(byte* ptr=data)
        {
            // Fill values with 0
            for(int i=0; i<Size; i++)
            {
                ptr[i]=0;
            }
        }
    }

    public void Store(byte[] array, int index)
    {
        fixed(byte* ptr=data)
        {
            // find max elements remaining
            int N=Math.Min(index + array.Length, Size) - index;
            // Fill values from input bytes
            for(int i=0; i<N; i++)
            {
                ptr[index+i]=array[i];
            }
        }
    }

    public byte[] ToArray()
    {
        byte[] array=new byte[Size];
        fixed(byte* ptr=data)
        {
            // Extract all data
            for(int i=0; i<Size; i++)
            {
                array[i]=ptr[i];
            }
        }
        return array;
    }
}

unsafe class Program
{
    static void Main(string[] args)
    {
        Buffer buffer=new Buffer();
        // buffer contains 100 bytes
        int size=sizeof(Buffer);
        // size = 100
        buffer.Clear();
        // data = { 0, 0, 0, ... }
        buffer.Store(new byte[] { 128, 207, 16, 34 }, 0);

        byte[] data=buffer.ToArray();
        // { 128, 207, 16, 34, 0, 0, ... }
    }
}

(PS需要使用编译允许不安全的代码进行编译)

答案 4 :(得分:0)

使用类而不是结构。

答案 5 :(得分:0)

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

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