Jam*_* Ko 9 .net c# string immutability
请考虑以下代码:
unsafe
{
string foo = string.Copy("This can't change");
fixed (char* ptr = foo)
{
char* pFoo = ptr;
pFoo[8] = pFoo[9] = ' ';
}
Console.WriteLine(foo); // "This can change"
}
Run Code Online (Sandbox Code Playgroud)
这将创建一个指向第一个字符的指针,将其foo重新指定为变为可变,并将字符8和9的位置更改为' '.
注意我从未真正重新分配过foo; 相反,我通过修改其状态或改变字符串来改变其值.因此,.NET字符串是可变的.
这样做效果很好,事实上,以下代码:
unsafe
{
string bar = "Watch this";
fixed (char* p = bar)
{
char* pBar = p;
pBar[0] = 'C';
}
string baz = "Watch this";
Console.WriteLine(baz); // Unrelated, right?
}
Run Code Online (Sandbox Code Playgroud)
将打印"Catch this"由于字符串文字实习.
这有很多适用的用途,例如:
string GetForInputData(byte[] inputData)
{
// allocate a mutable buffer...
char[] buffer = new char[inputData.Length];
// fill the buffer with input data
// ...and a string to return
return new string(buffer);
}
Run Code Online (Sandbox Code Playgroud)
被替换为:
string GetForInputData(byte[] inputData)
{
// allocate a string to return
string result = new string('\0', inputData.Length);
fixed (char* ptr = result)
{
// fill the result with input data
}
return result; // return it
}
Run Code Online (Sandbox Code Playgroud)
如果您在速度关键领域(例如编码)工作,这可以节省潜在的巨大内存分配/性能成本.
我猜你可以说这不算数,因为它"使用hack"来使指针变得可变,但是再一次是C#语言设计者支持首先将字符串赋值给指针.(事实上,这样做是所有 的 时间在内部String和StringBuilder,所以在技术上你可以使自己的StringBuilder与此有关.)
那么,.NET字符串真的应该被认为是不可变的吗?
§18#C#语言规范(该fixed语句)专门解决了通过固定指针修改字符串的情况,并指出这样做会导致未定义的行为:
通过固定指针修改托管类型的对象可能导致未定义的行为.例如,因为字符串是不可变的,所以程序员有责任确保不修改指向固定字符串的指针引用的字符.
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |