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';
}
这两种方法都根据某种特定算法将字节数组编码为字符串。第一个创建一个字符串,并使用指针写入单个字符。 第二个创建一个char数组,并最终使用该数组实例化一个字符串。
我知道字符串是不可变的,并且多个字符串声明可以指向同一分配的内存。另外,根据this article,除非绝对必要,否则不要使用不安全的字符串修改。
我的问题: 什么时候可以安全地使用Encode1示例代码中使用的“不安全的字符串修改”?
PS。我知道Span and Memory和string.Create方法是较新的概念。我只是对此特殊情况感到好奇。
修改
感谢您的所有回复。
我的问题中的“安全”一词也许比它带来的好处更令人困惑。我不是说它与unsafe
关键字相反,而是白话。
答案 0 :(得分:0)
最终,只有当您拥有该字符串并且尚未暴露于任何可能期望它的外部代码时,这种“安全”(就白话意义而言,而不是unsafe
意义上)是一成不变的。唯一一次看到这种情况的时间是 ,当您正在构建新的string
时,您不能仅使用GetString
Encoding
上的方法-例如,因为源数据是不连续的,并且可能跨越多个Encoder
步骤。
因此,基本上,Encode1
中所示的方案是分配合理长度的新string
,然后立即覆盖字符数据,这是唯一合理的用法。一旦字符串发狂了,那就让它保持不变。
但是,如果您即使是远程都可以避免:我会的。在Encode1
的上下文中绝对有道理,但是...
特别要谨慎的一种情况:内联字符串(常量,文字等);您不拥有这些。