为什么不能在 C# 7.2 的结构中同时使用只读缓冲区和固定大小缓冲区

问题描述 投票:0回答:2

随着 C# 7.2 的发布,现在可以拥有

readonly
结构,这在许多情况下可以提高性能。

对于我的一个结构,我使用固定大小的字节数组来实际保存数据。但是,当我标记

struct
和字节数组字段
readonly
时,C# 编译器抱怨
readonly
在该字段上无效。为什么我不能在
fixed
的字段上同时拥有
readonly
struct

readonly unsafe struct MyStruct {
  readonly fixed byte _Value[6]; //The modifier 'readonly' is not valid for this item.
}
c# struct unsafe c#-7.2
2个回答
1
投票

因为 C# 规范是这样说的(而且它总是这样,甚至在 c# 7.2 之前)。在 18.7.1 节中,名为“固定大小缓冲区声明”的部分中,允许在

fixed
缓冲区声明中使用以下修饰符:

公共

受保护

内部

私人

不安全

这里没有

readonly
。如果您考虑一下 - 它无论如何都没有多大意义,因为固定缓冲区大小由指针表示,并且您不能限制对指针的写访问。例如:

var s = new MyStruct();
byte* value = s._Value;
// how can you prevent writing to `byte*`?

0
投票

实际上有一个技巧可以在只读结构中有一个只读固定字段: 只需将你的固定嵌入一个专用结构中即可;-)

unsafe struct MyFixed {
    public fixed byte _v[6];

    public MyFixed(byte[] bs)
    {
        for (int i=0;i!=6;i++)
            _v[i]=bs[i];
    }
 }

readonly struct MyStruct {
    readonly public MyFixed Values;

    public MyStruct(byte[] bs){
        Values = new MyFixed(bs);
    }

static unsafe byte GetFixed(in MyStruct _ms)
=> _ms.Values._v[1];
        
static unsafe byte SetFixed(in MyStruct _ms)
=> _ms.Values._v[1] = 0;

我补充说:

  • 一个构造函数,只是为了能够测试 sharplab。
  • 从外部获取和设置,编译器检测并报告 Set 中的只读访问。

这清楚地表明您面临的限制只是任意的,并且可以在 Roslyn 中轻松修复(双关语意);-)

© www.soinside.com 2019 - 2024. All rights reserved.