Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/libraries/System.Private.CoreLib/src/System/String.cs
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,25 @@ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value)
}

/// <summary>
/// Returns a reference to the first element of the String. If the string is null, an access will throw a NullReferenceException.
/// Returns a read-only reference to the first element of the String. If the string is null, an access will throw a NullReferenceException.
/// </summary>
/// <remarks>
/// <para>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source of truth for official docs in dotnet-api-docs repo has number of other remarks: https://learn.microsoft.com/en-us/dotnet/api/system.string.getpinnablereference?view=net-10.0

It may be better to do the changes there.

/// The <see cref="string"/> type is immutable: the value of a <see cref="string"/> object
/// cannot be changed after the object is created. The reference returned by this method is
/// <c>ref readonly</c> and must only be used for reading characters; writing to
/// the referenced memory is not permitted and results in undefined behavior, including
/// potential corruption of the managed heap.
/// </para>
/// <para>
/// When using this method (or the equivalent C++/CLI <c>PtrToStringChars</c> function) to
/// obtain a pinned interior pointer to the string's character data, the resulting pointer
/// must be treated as read-only. In C++/CLI, <c>PtrToStringChars</c> exposes the pointer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we want to be talking about C++/CLI specific methods in the documentation for System.String.

The discussion of C++/CLI PtrToStringChars should be in C++/CLI documentation.

/// as <c>const wchar_t*</c> to reflect this constraint. Casting away <c>const</c>
/// and writing through the pointer will silently corrupt the CLR heap and may cause
/// crashes or incorrect behavior at an unrelated location later in program execution.
/// </para>
/// </remarks>
Comment on lines +523 to +539

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method already returns a ref readonly char; why do we need to get into this much detail that we should not mutate the returned memory?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree - this method alone is the least of the problem since it returns ref readonly.

The general issue is covered in https://learn.microsoft.com/en-us/dotnet/standard/unsafe-code/best-practices#17-string-mutations . There are many ways to get the pointer to string characters using unsafe code, it applies to all of them.

[EditorBrowsable(EditorBrowsableState.Never)]
[NonVersionable]
public ref readonly char GetPinnableReference() => ref _firstChar;
Expand Down
Loading