Strings can always be passed as ReadOnlySpan<char>, but if what you have is a span, that can't be passed as a string without allocating. For example, here is a scenario where a previous API call populated some spans:
var productCode = (stackalloc char[39]);
var componentCode = (stackalloc char[39]);
if (PInvoke.MsiGetShortcutTarget(shortcutPath, productCode, null, componentCode) != 0)
{
componentPath = null;
return false;
}
const int bufferSize = 1024;
var buffer = (stackalloc char[bufferSize]);
uint length = bufferSize;
var result = PInvoke.MsiGetComponentPath(productCode.ToString(), componentCode.ToString(), buffer, ref length);
In order to avoid those two ToString allocations, I would now have to introduce an unsafe block for the first time, and use three fixed statements to pin the three spans being passed to MsiGetComponentPath.
Alternatively, the friendly overloads could always take ReadOnlySpan<char> instead of string.
Strings can always be passed as
ReadOnlySpan<char>, but if what you have is a span, that can't be passed as a string without allocating. For example, here is a scenario where a previous API call populated some spans:In order to avoid those two ToString allocations, I would now have to introduce an
unsafeblock for the first time, and use threefixedstatements to pin the three spans being passed to MsiGetComponentPath.Alternatively, the friendly overloads could always take
ReadOnlySpan<char>instead ofstring.