在C#中如何设置字符串中某个索引处的字符?

43
someString[someRandomIdx] = 'g';

会给我一个错误。

如何实现上述要求?


http://msdn.microsoft.com/en-us/library/system.string.insert.aspx - Pranay Rana
不变性是一个强大的工具。 - Dykam
可能是在字符串中替换给定索引处的字符?的重复问题。 - psubsee2003
7个回答

65

如果它的类型是string,那么你不能这样做,因为字符串是不可变的——一旦设置就不能更改。

要实现你想要的效果,可以使用StringBuilder

StringBuilder someString = new StringBuilder("someString");

someString[4] = 'g';

更新

为什么要使用 string 而不是 StringBuilder?有许多原因。以下是我想到的一些原因:

  • 访问字符串的值更快。
  • 字符串可以被池化(这并不总是发生),所以如果您创建一个具有相同值的字符串,则不会使用额外的内存。
  • 字符串是不可变的,所以它们在基于哈希的集合中效果更好,并且它们本质上是线程安全的。

字符串和StringBuilder之间有什么区别?也就是说,为什么我不能在任何地方都使用StringBuilder? - matt
有关 StringBuilder 类的更多信息,请访问:http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx - Matt Ellen
@matt,string是不可变的,而StringBuilder是可变的,当您想要修改给定字符串时,它们之间有巨大的性能差异。请阅读这个这个以获取更多详细信息。 - RBT

40

C# 字符串是不可变的。您应该创建一个具有修改内容的新字符串。

 char[] charArr = someString.ToCharArray();
 charArr[someRandomIdx] = 'g'; // freely modify the array
 someString = new string(charArr); // create a new string with array contents.

7

既然没有人提到一行解决方案:

someString = someString.Remove(index, 1).Insert(index, "g");

1
字符串是不可变的,因此方法始终返回一个新字符串。你将从调用删除中获得一个新字符串,然后从插入中获得另一个字符串。请使用Matt Ellen的答案代替。 - Ruhrpottpatriot
1
@Ruhrpottpatriot,你真认为我不知道吗?有时候性能并不是很重要的障碍,所以如果一行代码就可以完成任务,很多人就不会费心去写一个单独的扩展方法之类的了。 - polfosol ఠ_ఠ
2
你可能知道,但其他人可能不知道。根据字符串大小,这可能会产生沉重的惩罚,而你完全没有提到。你的方法客观上比被接受的答案更糟糕。而且,不,代码在一两行之间的可读性并不大到你可以将其作为论据提出。 - Ruhrpottpatriot
@Ruhrpottpatriot 顺便说一下,ToCharArray()StringBuilder 更快。其他人——你所关心的人也不应该使用 Matt Ellen 的答案,因为 Mehrdad Afshari 提出的那个更有效率。请参见此评论 - polfosol ఠ_ఠ
一个char数组更快,这是正确的(而且根据我的测试,随着长度增加,优势会显著缩小),但这与我们讨论的代码无关。 - Ruhrpottpatriot

3

如果你一定要更改一个字符串的现有实例,可以使用不安全代码的方法:

        public static unsafe void ChangeCharInString(ref string str, char c, int index)
        {
            GCHandle handle;
            try
            {
                handle = GCHandle.Alloc(str, GCHandleType.Pinned);
                char* ptr = (char*)handle.AddrOfPinnedObject();
                ptr[index] = c;
            }
            finally
            {
                try
                {
                    handle.Free();
                }
                catch(InvalidOperationException)
                {
                }
            }
        }

2
知道这个很好,谢谢,但请不要这样做 :) - Roberto

1

请查看这篇文章,了解如何在C#中修改字符串内容。 字符串是不可变的,因此必须将它们转换为中间对象,然后才能进行修改。


0
如果您想要介绍Also(...)

public static class Ext
{
    public static T Also<T>(this T arg, Action<T> act) 
    { 
        act(arg); return arg; 
    }

    public static string ReplaceCharAt(this string str, int index, char replacement) => 
        new string(str.ToCharArray().Also(arr => arr[index] = replacement));
}


可以用作:
void Main()
{
    string str = "This is string";
    Console.WriteLine(str);
    
    var str2 = str.ReplaceCharAt(0,'L').ReplaceCharAt(1,'i').ReplaceCharAt(2,'l').ReplaceCharAt(3,'y');
    Console.WriteLine(str2);
}

要获得以下输出:

enter image description here


-2

你也可以使用Insert()方法,例如:somestring.Insert(index,data)


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