c# - .NET 字符串真的应该被认为是不可变的吗?

标签 c# .net 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"
}

这将创建一个指向 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?
}

由于字符串文字驻留,将打印"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);
}

被替换为:

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
}

如果您在速度关键领域(例如编码)工作,这可能会节省潜在的巨大内存分配/性能成本。

我想您可能会说这不算数,因为它“使用 hack”使指针可变,但又是 C# 语言设计者首先支持将字符串分配给指针。 (事实上​​,这是在 StringStringBuilder 内部完成的 all the time,所以从技术上讲,您可以用它来制作自己的 StringBuilder。)

那么,.NET 字符串真的应该被认为是不可变的吗?

最佳答案

C# 语言规范的第 18.6 节(fixed 语句)专门解决了通过固定指针修改字符串的情况,并指出这样做会导致未定义的行为:

Modifying objects of managed type through fixed pointers can results in undefined behavior. For example, because strings are immutable, it is the programmer’s responsibility to ensure that the characters referenced by a pointer to a fixed string are not modified.

关于c# - .NET 字符串真的应该被认为是不可变的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31930705/

相关文章:

c# - 使用数据中的参数调用 C# 方法

c# - 无法在回调方法中添加 View 并在 Windows Phone 7 中出现错误 "UnauthorizedAccessException"

c# - 如何刷新列表框的数据源

r - 拆分为列时,为较短的字符串填充 NA 列

c# - ViewModel 和 Command 之间的通信

c# - 如何在输入时保持对 TextBox 的关注?

.net - WCF和可选参数

c# - 从另一个文件访问私有(private)类

php - 如何在 PHP 中用空字符串替换 ?myuser=number

python - 如何使用python在字符串中一定数量的字符后插入空格?