String.Copy
is not removed in .NET Core ‒ in fact it is in .NET Standard 2.0 and thus available in all common .NET environments.
In .NET Core, this is what it looks like:
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This API should not be used to create mutable strings. See https://go.microsoft.com/fwlink/?linkid=2084035 for alternatives.")]
public static unsafe string Copy(string str)
{
ArgumentNullException.ThrowIfNull(str);
string result = FastAllocateString(str.Length);
Buffer.Memmove(
elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below
destination: ref result._firstChar,
source: ref str._firstChar);
return result;
}
You can see EditorBrowsableState.Never
there to detract people from using it, and Obsolete
with the explanation. The explanation says:
This API should not be used to create mutable strings. See https://go.microsoft.com/fwlink/?linkid=2084035 for alternatives.
This means that if you are using it to create a character buffer to copy data to, you should not! There are far better alternatives, such as String.Create
which gives you a Span<char>
to copy the data to.
However, the message implies that you should only worry if you actually use it to create mutable strings. The primary use of the method is to return a copy of str
such that (object)str != String.Copy(str)
. If you need it for this purpose and this purpose alone (maybe you are using it in a ConditionalWeakTable
), you are safe to use it.
If you are still unsure, there is this option which guarantees to create a new buffer:
static string Copy(string str)
{
return String.Create(str.Length, str, static (buffer, s) => s.AsSpan().CopyTo(buffer));
}
Just note that String.Create
returns String.Empty
if the length is 0, and it could also, theoretically, perform interning of the result before returning it. The current implementation does not go as far, but I could imagine, realistically, that this could be viable for very short lengths, where the buffer could be allocated on the stack first and compared to an internal table in case a previously-created (weakly-referenced) string is available.
Copy
method? – EmeryString.Copy
? It's pretty unusual to need ti, and is generally worse than using=
(as it involves creating a copy in a way that is almost always unnecessary). – Eislernew String(a)
? – Gigastring.Copy
was used in the copy constructor. – DecentralizeString(string)
is not present in .net core too. :( – Decentralize