随着 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# 规范是这样说的(而且它总是这样,甚至在 c# 7.2 之前)。在 18.7.1 节中,名为“固定大小缓冲区声明”的部分中,允许在
fixed
缓冲区声明中使用以下修饰符:
新
公共
受保护
内部
私人
不安全
这里没有
readonly
。如果您考虑一下 - 它无论如何都没有多大意义,因为固定缓冲区大小由指针表示,并且您不能限制对指针的写访问。例如:
var s = new MyStruct();
byte* value = s._Value;
// how can you prevent writing to `byte*`?
实际上有一个技巧可以在只读结构中有一个只读固定字段: 只需将你的固定嵌入一个专用结构中即可;-)
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;
我补充说:
这清楚地表明您面临的限制只是任意的,并且可以在 Roslyn 中轻松修复(双关语意);-)