在C#字符串中更改特定索引处的字符的默认方法是什么?

4

我可以看到你有一个字符串:

string s = "abc";

我希望将第二个字符更改为'd',使其变为"adc"。我认为以下代码可以实现:

s[1] = 'd';

然而,我遇到了一个错误:
Property or indexer 'string.this[int] 'cannot be assigned to -- it is read only

我该如何完成这个简单的任务(不使用相对复杂的子字符串方法)?

2
你不能只改变一个字符,而需要更复杂的方法,是因为字符串是不可变的——没有办法修改它们的实例,而所有的辅助方法都会返回新的、稍微修改过的字符串。这至少可以避免你困惑地弄清楚为什么一个字符串实例发生了改变。 - Katana314
1
你有没有看过:http://msdn.microsoft.com/en-us/library/fk49wtc1%28v=vs.110%29.aspx? - user628985
@Katana314 ... 是的,我已经预料到了这个原因,但我从一个基类返回了一个字符串,在极少数情况下我必须更改一个字符。 - Michel Keijzers
5个回答

12

String 是不可变的。你可以使用 StringBuilder 来改变一个字符串:

var s = "abc";
var sb = new StringBuilder(s);
sb[1] = 'd';
s = sb.ToString();

1
给我10秒钟,看我能不能完成 :) - Soner Gönül

2
错误信息很清楚, String.Chars 属性 是只读的。您不能对其进行赋值。
这是它的定义方式:
public char this[
    int index
] { get; }

如您所见,这里没有 `set` 访问器。
您可以使用 String.RemoveString.Insert 方法来实现。以下是在 LINQPad 上的示例;
string s = "abc";
s = s.Remove(1, 1).Insert(1, "d");
s.Dump(); //adc

记住,string不可变类型。你无法更改它们。它在创建后无法修改。即使你认为你改变了它们,实际上你会创建一个新的字符串对象。
作为替代方案,你可以使用StringBuilder类,它表示可变字符串,因为StringBuilder.Chars属性具有get和set访问器。
var sb = new StringBuilder("abc");
sb[1] = 'd';
sb.Dump();  // adc

2

虽然不建议这样做,但是您可以使用unsafe上下文来实现:

fixed (char* pfixed = s)
    pfixed[1] = 'd';

我宁愿选择一个整洁的解决方案,但仍然加1,因为这是一个有效的答案。 - Michel Keijzers
1
当然!这个答案只是提供信息。谢谢。 - Dmitry

1

字符串是不可变的。你不能改变一个字符串,只能创建一个新的字符串。如果要修改一个字符串,你应该使用 StringBuilder


1
你可以使用 Enumerable.Select:

string s = "abc";
string n = new string(s.Select((c, index) => 
            {
                if (index == 1)
                    return 'd';
                else
                    return c;
            }).ToArray());
Console.WriteLine(n);  // adc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接