3

我有一个结构定义如下:

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

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

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

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

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

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

4

6 回答 6

2

这个怎么样:

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

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

于 2013-10-25T19:01:54.090 回答
2

固定数组缓冲区怎么样:

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 需要编译允许不安全的代码

于 2013-10-25T18:39:09.300 回答
2

你不能有一个无参数的构造函数,你不能在结构中定义一个大小为大小的数组,这会给你一个结构构造函数,它带有一个sizeas 参数,例如:

public struct check
{
    public int[] x;
    public check(int size)
    {
        x = new int[size];
    }
}
于 2013-10-25T18:12:00.897 回答
1

使用类而不是结构。

于 2013-10-25T18:47:37.437 回答
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

于 2013-10-25T18:31:17.543 回答
0

这可能会有很大帮助。我已经创建了结构 MyX,Struct 包含方法 ToByte 和 to 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]);
    }
于 2018-02-07T15:03:43.987 回答