Reputation: 3689
With the release of C# 7.2 there is now the ability to have readonly
structs, which in many cases can improve performance.
For one of my structs I am using a fixed-size byte array to actually hold the data. However when I marked the struct
and the byte array field readonly
, C# compiler complained that readonly
is not valid on the field. Why can't I have both fixed
and readonly
on a field in a struct
?
readonly unsafe struct MyStruct {
readonly fixed byte _Value[6]; //The modifier 'readonly' is not valid for this item.
}
Upvotes: 7
Views: 1164
Reputation: 65
Actually there is a trick to have a readonly fixed field in a readonly struct: just embed your fixed inside a dedicated struct ;-)
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;
I added:
This clearly demonstrate that the limitation you faced is just arbitrary and could easily be fixed (pun intended) in Roslyn ;-)
Upvotes: 0
Reputation: 101543
Because C# specification says so (and it always did, even before c# 7.2). In 18.7.1 section, named "Fixed size buffer declarations", the following modifiers are allowed on fixed
buffer declaration:
new
public
protected
internal
private
unsafe
No readonly
here. If you think about it - it doesn't make much sense anyway, because fixed buffer size is represented by a pointer, and you cannot restict write access to a pointer. For example:
var s = new MyStruct();
byte* value = s._Value;
// how can you prevent writing to `byte*`?
Upvotes: 1