何时在 C# 中使用 'unsafe string modifications' 是安全的?


private const int RESULT_LENGTH = 10;
public static unsafe string Encode1(byte[] data)
{
var result = new string('0', RESULT_LENGTH); // memory allocation
fixed (char* c = result)
{
for (int i = 0; i < RESULT_LENGTH; i++)
{
c[i] = DetermineChar(data, i);
}
}
return result;
}

public static string Encode2(byte[] data)
{
var chars = new char[RESULT_LENGTH]; // memory allocation
for (int i = 0; i < RESULT_LENGTH; i++)
{
chars[i] = DetermineChar(data, i);
}
return new string(chars); // again a memory allocation
}
private static char DetermineChar(byte[] data, int index)
{
// dummy algorithm.
return 'a';
}

这两种方法都根据特定的算法将字节数组编码为字符串。第一个创建一个字符串,并使用指针写入单个字符。第二个创建一个字符数组,并最终使用该数组实例化一个字符串。

我知道字符串是不可变的,并且多个字符串声明可以指向同一个分配的内存。此外,根据本文,除非绝对必要,否则不应该使用不安全的字符串修改。

我的问题:何时可以安全地使用Encode1示例代码中使用的"不安全字符串修改">

PS。我知道Span和Memory以及字符串等较新的概念。创建方法。我只是对这个具体的案例感到好奇。

编辑

感谢您的回复。也许我的问题中的"安全"这个词比它带来的任何好处都更令人困惑。我的意思并不是说它与unsafe关键字相反,而是说它是一个白话词。

最终,唯一"安全"的时候(在白话意义上,而不是在unsafe意义上(是当您拥有字符串,并且它还没有暴露给任何可能认为它是不可变的外部代码时。唯一常见的是在构建新的string时,而不能在Encoding上仅使用GetString方法,例如,因为源数据是不连续的,并且可能跨越多个Encoder步骤。

因此,基本上,Encode1中所示的场景是唯一合理的用法,即它分配一个已知长度的新string,然后立即覆盖字符数据。一旦字符串处于野生状态:就让它保持不变。

然而,如果你甚至远程都可以避免:我会的。这在Encode1的上下文中肯定是有意义的,但是。。。

有一种情况需要特别小心:内部字符串(常量、文字等(;你不拥有这些。

最新更新