Skip to content

API proposal: MemoryMarshal.GetRawArrayData #29003

@GrabYourPitchforks

Description

@GrabYourPitchforks

(Related to https://github.com/dotnet/corefx/issues/33706, but more narrowly scoped.)

Proposal

namespace System.Runtime.InteropServices
{
    public static class MemoryMarshal
    {
        // new method on existing MemoryMarshal type
        public static ref T GetRawArrayRef<T>(T[] array);
    }
}

Motivation

Per the feedback at https://github.com/dotnet/corefx/issues/33706#issuecomment-442145588, third-party libraries may want to perform certain optimizations that today can only be performed within coreclr itself because we know the internal layout of SzArray instances.

Behavior

If array is null, this results in a standard NullReferenceException (see https://github.com/dotnet/corefx/issues/36133#issuecomment-474389127). Otherwise it returns a reference to the element at index 0 in the array, even if the array is empty.

Per ECMA-335 (PDF), § II.14.4.2, it is legal for a managed pointer (type T&) to point just past the end of an array to where the next value would have been stored. Such T& cannot be safely dereferenced, but it is guaranteed to be tracked properly by the GC, and it can be used as an input argument in binary operators like add or clt.

Because it is possible to get a real GC-tracked managed pointer (T&), but because we cannot guarantee that it's safe to dereference, the GetRawArrayData method belongs on MemoryMarshal or some other "unsafe" type. The Unsafe static class is also a candidate for where this API can live, but it does not have any existing API surface for dealing with T[] inputs.

Developers who want a T& that's always safe to dereference can continue to use the standard syntax for getting a reference to the first array element:

ref T myRef = ref theArray[0]; // runtime will bounds check for you

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions