string myString = "ABCDEFGHIJ";
string modifiedString = new StringBuilder(myString){[3]='Z', [4]='X'}.ToString();
Дозвольте пояснити своє рішення.
Враховуючи заяву проблеми про зміну рядка в його двох конкретних положеннях ("позиція 4 до позиції 5") з двома символами "Z" та "X", і запит полягає в використанні індексу позиції для зміни рядка, а не рядка Замінити ( ) метод (можливо, через можливість повторення деяких символів у фактичному рядку), я вважаю за краще використовувати мінімалістичний підхід для досягнення мети над використанням, Substring()
а також рядком Concat()
або рядком Remove()
та Insert()
підходом. Хоча всі ці рішення слугуватимуть цілі у досягненні тієї самої мети, але це просто залежить від особистого вибору та філософії врегулювання з мінімалістичним підходом.
Повертаючись до мого рішення, згадайте вище, якщо ми детальніше розглянемоstring
іStringBuilder
, вони внутрішньо розглядають заданий рядок як масив символів. Якщо ми подивимось на реалізацію,StringBuilder
вона підтримує внутрішню змінну на зразок " internal char[] m_ChunkChars;
" для захоплення заданого рядка. Оскільки це внутрішня змінна, ми не можемо безпосередньо отримати доступ до неї. Щоб зовнішній світ мав змогу отримати доступ та змінити цей масив символів, StringBuilder
відкриває їх через властивість індексатора, яка виглядає приблизно так, як нижче
[IndexerName("Chars")]
public char this[int index]
{
get
{
StringBuilder stringBuilder = this;
do
{
// … some code
return stringBuilder.m_ChunkChars[index1];
// … some more code
}
}
set
{
StringBuilder stringBuilder = this;
do
{
//… some code
stringBuilder.m_ChunkChars[index1] = value;
return;
// …. Some more code
}
}
}
Згадане вище моє рішення використовує можливість цього індексатора безпосередньо змінювати внутрішньо підтримуваний масив символів, який IMO ефективний і мінімалістичний.
BTW; ми можемо переписати вищезазначене рішення більш детально, щось на зразок нижче
string myString = "ABCDEFGHIJ";
StringBuilder tempString = new StringBuilder(myString);
tempString[3] = 'Z';
tempString[4] = 'X';
string modifiedString = tempString.ToString();
У цьому контексті також хотілося б зазначити, що у випадку, якщо string
він також має властивість індексатора як засіб викрити свій внутрішній масив символів, але в цьому випадку він має лише властивість Getter (а не Setter), оскільки рядок є незмінним за своєю природою. І саме тому нам потрібно використовувати StringBuilder
для зміни масиву символів.
[IndexerName("Chars")]
public extern char this[int index] { [SecuritySafeCritical, __DynamicallyInvokable, MethodImpl(MethodImplOptions.InternalCall)] get; }
І останнє, але не менш важливе, це рішення найкраще підходить для цієї конкретної проблеми, коли запит - замінити лише кілька символів відомим індексом позиції наперед. Це може бути не найкращим чином, коли вимога полягає в зміні досить тривалої рядки, тобто кількість символів, які потрібно змінити, є великими числами.