-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
I just spent an hour or so brainstorming with @JeremyKuhne about issues he's had with fixed buffers, readonly struct, and ref structs. He'd like to declare some structures for interop that are fairly large, and would like to avoid having them copied by the compiler for defensive reasons. There are a few corners of the language that make this awkward in some circumstances.
For example, if you declare a struct readonly, so as to avoid defensive copies when calling its methods, then you cannot place a fixed struct inside it (because a fixed struct can't be declared readonly, and a readonly struct cannot contain a field that isn't declared readonly).
We came up with the following four (prioritized) suggestions for how to improve things.
-
Have a way to get warnings for situations in which the compiler would or does produce a defensive copy. Because the compiler's precise rules are subtle, the most precision would be achieved if this were done in the compiler. One way to do this would be to have the compiler always produce a warning when a compiler-generated defensive copy is generated for a struct type that has some particular annotation on it. One could also imagine doing this in an analyzer, though that would be harder and possibly less precise. We placed this number one on our list because no matter the other tools are available to address the issues, this is needed to know when to deploy them. (Warning for struct copy of selected types roslyn#26937) [Under consideration as part of a warning wave in C# 9.0]
-
Permit a fixed field to be declared inside a readonly struct. (Permit a fixed field to be declared inside a readonly struct. #1793) [Under consideration for C# 9.0]
-
Permit a "readonly" modifier to be placed on the individual function members of the struct, which would be a declaration that the
thisparameter isref readonlyfor that member instead ofrefwhich is usual. This is a little bit like the semantics of areadonly struct, but applied to the members one-by-one. Invocations of such members would not require a defensive copy of the receiver if the receiver is readonly. (See Champion: Readonly members on structs (16.3, Core 3) #1710) [Done in C# 8.0] -
Provide some kind of new autoproperty syntax for a property of type Span or ReadonlySpan with a compiler-generated fixed backing field, perhaps something like
fixed ReadonlySpan<int> fixedBuffer[16] { get; }. The compiler would generate a fixed field to back it and would provide the implementation of thegetaccessor. [Not currently under consideration. Although there is more boilerplate, it is possible that the other issues might make the effect of this achievable by hand] -
A
fixedstatement should not be required on a fixed field of aref struct, because it is never moveable. (Do not require fixing a fixed field of a ref struct #1792) [Under consideration for C# 9.0]
After some discussion, we'll probably promote these individual ideas to separate, possibly championed issues.