The set of types that can participate in `fixed` is hardcoded and limited to arrays and `System.String`. Hardcoding "special" types does not scale when new primitives such as `ImmutableArray<T>`, `Span<T>`, `Utf8String` are introduced.
In addition, the current solution for `System.String` relies on a fairly rigid API. The shape of the API implies that `System.String` is a contiguous object that embeds UTF16 encoded data at a fixed offset from the object header. Such approach has been found problematic in several proposals that could require changes to the underlying layout.
It would be desirable to be able to switch to something more flexible that decouples `System.String` object from its internal representation for the purpose of unmanaged interop.
## Detailed design
[design]: #detailed-design
## *Pattern* ##
A viable pattern-based <20>fixed<65> need to:
- Provide the managed references to pin the instance and to initialize the pointer (preferably this is the same reference)
- Convey unambiguously the type of the unmanaged element (i.e. <20>char<61> for <20>string<6E>)
- Prescribe the behavior in "empty" case when there is nothing to refer to.
- Should not push API authors toward design decisions that hurt the use of the type outside of `fixed`.
I think the above could be satisfied by recognizing a specially named ref-returning member:
`ref [readonly] T DangerousGetPinnableReference()`.
finally // finally can be omitted when not observable
{
// "unpin" the object
_pinned = nullptr;
}
```
## Drawbacks
[drawbacks]: #drawbacks
- DangerousGetPinnableReference is intended to be used only in `fixed`, but nothing prevents its use in safe code, so implementor must keep that in mind.
## Alternatives
[alternatives]: #alternatives
Users can introduce DangerousGetPinnableReference or similar member and use it as