Страницы

Поиск по вопросам

воскресенье, 16 февраля 2020 г.

Изменение значения внутри строки

#c_sharp #строки


Есть ли способ изменить значение внутри строки не переводя её в массив символов?
Например "Машинная сила" в "Машинная пила".
    


Ответы

Ответ 1



Нет. Строки в C# неизменяемые, так что вам придётся создавать новую строку, изменить уже существующую строку невозможно*. Если нужна запись символов по индексу, то проще всего перегнать строку в StringBuilder, в котором можно менять значения по индексу, а также добавлять их и удалять. А после окончания обработки снова перегнать в строку: string s = "Машинная сила"; StringBuilder sb = new StringBuilder(s); sb[9] = 'п'; s = sb.ToString(); Если нужно заменить один символ, может быть проще всего откусить подстроку до этого символа и после, и сконкатенировать. Обратите внимание, что в коде у меня каждый раз создаётся новая строка, так что те, кто имел ссылку на старую строку, не увидят изменений. *Ну то есть возможно через unsafe-код или там рефлексию, но если вы так сделаете, ваш тимлид и вся команда прибегут бить вас после первого же code review.

Ответ 2



Можно использовать unsafe-код, если нужно менять строку. Редко когда такое действительно оправдано, но возможно вам нужно чтобы ваш код очень быстро работал. В общем это можно делать на свой страх и риск, когда вы уверены, что вы всё предусмотрели и вам нужна действительно огромная производительность. string s = "Машинная сила"; unsafe { fixed (char* chars = s) { chars[9] = 'п'; } } Чтобы это компилировалось в свойствах проекта следует отметить галочку Allow unsafe code. Побочные эффекты Однако из-за интернирования строк в C# также строки с тем же значением поменяются (спасибо @VladD за эту мысль): public static void Main() { A(); Console.WriteLine("Hello world"); // Выведет "Hello bugs!" } public static unsafe void A() { string s = string.Intern("Hello world"); fixed (char* p = s) { p[6] = 'b'; p[7] = 'u'; p[8] = 'g'; p[9] = 's'; p[10] = '!'; } } Без string.Intern данное поведение также сохраняется.

Комментариев нет:

Отправить комментарий