- "A strategy to hold ourselves hostage"
#1314
https://github.com/dotnet/csharplang/blob/7b5d0bbcd552e0541db4a5afdad3b75210037120/proposals/inline-arrays.md#the-foreach-statement
Following up from a previous discussion on inline arrays, we looked at foreach
support for inline
array types. The current implementation plan for foreach
on these types is to do it via Span<T>
or ReadOnlySpan<T>
; as these are
ref struct
types, they cannot be foreach
ed in an async
method. This restriction makes sense for inline arrays sometimes, as they are
more likely to be passed around via ref
than standard types. Refs can't live past an await
boundary, so this makes sense for such
variables. However, it doesn't make as much sense for inline arrays that are local by value: for example, a local of an inline array type
would not be foreachable in an async
method as proposed today. There are two possible improvements we could make here:
- Be more granular with
ref struct
usage inasync
methods. As long as theref struct
does not cross anasync
boundary, it should be safe to reference. If we were smarter aboutref struct
usage inasync
methods, then inline arrays would simply come along for the ride. It's not a perfect solution though, as there would still be errors for inline array values that can be safely lifted to a display class when aforeach
loopawait
ed in its body. - Have special lowering for inline arrays for async methods.
ref
s to inline arrays would continue to be blocked inasync
methods, as today, inline array values (mainly locals and parameters) can be safely lifted to a display class and iterated over acrossawait
boundaries without any issues around observability of changes.
These solutions are not mutually exclusive; we can do either one, both, or none. What we are fairly certain of at this point, though, is that
it is unlikely that we can fit either solution into C# 12. After some discussion, we decided that we are fine with shipping an initial version
of inline arrays that restricts foreach
in async
methods, and later loosen restrictions on it as we can.
We will support foreach
over inline arrays, even if it starts as restricted in async
methods. We will encourage alternate lowering strategies
and smarter ref
rules in async methods where we can, but that will be a longer-term effort.