29
someString[someRandomIdx] = 'g';

will give me an error.

How do I achieve the above?

Robert Harvey
  • 168,684
  • 43
  • 314
  • 475
matt
  • 3,771
  • 3
  • 28
  • 46

7 Answers7

49

If it is of type string then you can't do that because strings are immutable - they cannot be changed once they are set.

To achieve what you desire, you can use a StringBuilder

StringBuilder someString = new StringBuilder("someString");

someString[4] = 'g';

Update

Why use a string, instead of a StringBuilder? For lots of reasons. Here are some I can think of:

  • Accessing the value of a string is faster.
  • strings can be interned (this doesn't always happen), so that if you create a string with the same value then no extra memory is used.
  • strings are immutable, so they work better in hash based collections and they are inherently thread safe.
Matt Ellen
  • 9,933
  • 4
  • 61
  • 80
  • what is the difference between a string and a StringBuilder? i.e. why wouldn't I just use StringBuilders everywhere? – matt Jul 22 '10 at 07:37
  • for more information on the StringBuilder class: http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx – Matt Ellen Jul 22 '10 at 08:01
  • @matt `string` is immutable while `StringBuilder` is mutable and they have huge performance difference when you intend to modify a given string. Please read [this](https://stackoverflow.com/q/3069416/465053) and [this](https://stackoverflow.com/q/73883/465053) for more details. – RBT Jun 05 '18 at 15:09
34

C# strings are immutable. You should create a new string with the modified contents.

 char[] charArr = someString.ToCharArray();
 charArr[someRandomIdx] = 'g'; // freely modify the array
 someString = new string(charArr); // create a new string with array contents.
mmx
  • 390,062
  • 84
  • 829
  • 778
6

Since no one mentioned a one-liner solution:

someString = someString.Remove(index, 1).Insert(index, "g");
polfosol ఠ_ఠ
  • 1,470
  • 22
  • 33
  • Strings are immutable, therefore a method always returns a new string. You'll get a new string from the call to remove and then an additional string from insert. Use Matt Ellen's answer instead. – Ruhrpottpatriot Apr 23 '20 at 22:28
  • @Ruhrpottpatriot do you really think I didn't know that? Sometimes the performance is not a heavy barrier, so if a one-liner can get the job done, a lot of people won't bother writing a separate extension method and such. – polfosol ఠ_ఠ Apr 24 '20 at 15:25
  • __You__ might know that, but others might not. Depending on the string size this can incur a heavy penalty, which you completely fail to mention. Your method is objectively worse than the accepted answer. And no, the readability between one or two lines of code isn't that big that you can bring up that as an argument. – Ruhrpottpatriot May 06 '20 at 13:09
  • @Ruhrpottpatriot and by the way, `ToCharArray()` is way faster than `StringBuilder`. The others —who you are concerned with shouldn't use Matt Ellen's answer either, since the one Mehrdad Afshari proposed is more efficient. See [this comment](https://stackoverflow.com/questions/9367119/replacing-a-char-at-a-given-index-in-string?noredirect=1&lq=1#comment23716136_9367179). – polfosol ఠ_ఠ May 06 '20 at 13:40
  • A char array is faster, that is correct (and with greater length the advantage shrinks considerably according to my own tests), but that doesn't have anything to do with your code, which we talked about. – Ruhrpottpatriot May 07 '20 at 22:55
3

If you absolutely must change the existing instance of a string, there is a way with unsafe code:

        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)
                {
                }
            }
        }
1

Check out this article on how to modify string contents in C#. Strings are immutable so they must be converted into intermediate objects before they can be modified.

advait
  • 5,931
  • 3
  • 24
  • 36
0

If you're willing to introduce Also(...):

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));
Lily Finley
  • 2,208
  • 1
  • 13
  • 9
-1

you can also use Insert() method e.g. somestring.Insert(index,data)

ajay_whiz
  • 16,085
  • 3
  • 33
  • 44