Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不安全结构中的只读数组字段_C#_Arrays_Properties_Getter_Unsafe - Fatal编程技术网

C# 不安全结构中的只读数组字段

C# 不安全结构中的只读数组字段,c#,arrays,properties,getter,unsafe,C#,Arrays,Properties,Getter,Unsafe,这是原始声明: [StructLayout(LayoutKind.Explicit, Size = 16)] public unsafe struct X { [FieldOffset(0)] public ushort a; [FieldOffset(2)] public fixed byte b[14]; }; 我想将struct设为只读,但我不知道如何为数组编写getter。我能找到的唯一解决方案是getter方法: 是否可以为b编写getter属性而不是getter方法 ==更

这是原始声明:

[StructLayout(LayoutKind.Explicit, Size = 16)]
public unsafe struct X
{
  [FieldOffset(0)] public ushort a;
  [FieldOffset(2)] public fixed byte b[14];
};
我想将
struct
设为只读,但我不知道如何为数组编写getter。我能找到的唯一解决方案是getter方法:

是否可以为b编写getter属性而不是getter方法

==更新===

我还想处理存在多个数组字段的情况。例如:

[StructLayout(LayoutKind.Explicit, Size = 24)]
public unsafe struct Y
{
  [FieldOffset(0)] private ushort a;
  [FieldOffset(2)] private fixed byte b[14];
  [FieldOffset(16)] private fixed byte c[8];

  public ushort A { get { return a; } }
  public byte B(int i) { fixed (byte* p = b) { return p[i]; } }
  public byte C(int i) { fixed (byte* p = c) { return p[i]; } }
};

可以为b和c编写一个getter属性而不是getter方法吗?我想写
y.B[I]
y.C[I]
而不是
y.B(I)
y.C(I)

可以使用索引器属性访问特定索引处的数组。不幸的是,它需要在结构本身而不是B上定义,但这应该提供您想要的:

[StructLayout(LayoutKind.Explicit, Size = 16)]
public unsafe struct X
{
    [FieldOffset(0)]
    private ushort a;
    [FieldOffset(2)]
    private fixed byte b[14];

    public ushort A { get { return a; } }
    public byte this [int i]
    {
        get 
        {
            byte b1;
            fixed (byte* b2 = b)
            {
                b1 = b2[i];
            }
            return b1;
        }
    }
 }; 

我找到了一个基于以下理念的解决方案:


注意:可以简化为
fixed(byte*ptr=b){return ptr[i];}
——但本质上是这样的:这个+1是可以的,但我想索引的不是X本身,而是它的字段b。假设我有另一个数组字段,c。我想索引b,比如x.b[I],和c,比如x.c[I],其中x是x类型的。@Chris我扩展了这个问题,以包括存在多个数组字段的情况。谢谢你的帮助@MarcGravel感谢您的建议,我简化了问题中的代码。您应该只在非托管代码互操作中使用这样的声明。在这一点上,让结构成员只读不再意味着什么。您与之进行互操作的语言需要这样声明,可能是使用const。@HansPassant是的,我需要这个用于互操作代码。我有一个字节*来自第三方非托管库,在添加偏移量后,我将其转换为指向类似不安全结构的指针。我只想(1)阻止代码用户覆盖原始非托管数据,以及(2)修改getter中的一些字段。所以我将每个字段都设置为私有,并添加了getter。永远不要向客户端代码公开不安全的结构。这是不安全的,没有人喜欢打开这个选项。@HansPassant我需要这样做才能达到规定的性能。其实这个问题跟这个有关,
[StructLayout(LayoutKind.Explicit, Size = 16)]
public unsafe struct X
{
    [FieldOffset(0)]
    private ushort a;
    [FieldOffset(2)]
    private fixed byte b[14];

    public ushort A { get { return a; } }
    public byte this [int i]
    {
        get 
        {
            byte b1;
            fixed (byte* b2 = b)
            {
                b1 = b2[i];
            }
            return b1;
        }
    }
 }; 
[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct YB
{
  [FieldOffset(0)] private fixed byte b[14];
  public byte this[int i] { get { fixed (byte* p = b) { return p[i]; } } }
}

[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct YC
{
  [FieldOffset(0)] private fixed byte c[8];
  public byte this[int i] { get { fixed (byte* p = c) { return p[i]; } } }
}

[StructLayout(LayoutKind.Explicit, Size = 24)]
public unsafe struct Y
{
  [FieldOffset(0)] private ushort a;
  [FieldOffset(2)] private YB b;
  [FieldOffset(16)] private YC c;

  public ushort A { get { return a; } }
  public YB B { get { return b; } }
  public YC C { get { return c; } }
};