Изменчивые и неизменные - это английские слова, означающие «может измениться» и «не может измениться» соответственно. Значение слов одинаково в контексте ИТ; т.е.
изменяемая строка может быть изменена, и
неизменяемая строка не может быть изменена.
Значения этих слов в C # / .NET такие же, как и в других языках программирования / средах, хотя (очевидно) имена типов могут отличаться, как и другие детали.
Для записи:
String является стандартным неизменяемым строковым типом C # / .Net
StringBuilder стандартный тип изменяемой строки C # / .Net
Чтобы «внести изменения» в строку, представленную как C # String, вы фактически создаете новый Stringобъект. Оригинал Stringне изменился ... потому что он неизменен.
В большинстве случаев это лучше использовать, Stringпотому что это более легкая причина для них; Например, вам не нужно учитывать возможность того, что какой-то другой поток может «изменить мою строку». Однако, когда вам нужно создать или изменить строку, используя последовательность операций, может быть более эффективно использовать a StringBuilder.
И, наконец, для тех людей, которые утверждают, что a StringBuilderне является строкой, потому что она не является неизменной, документация Microsoft описывает StringBuilderтак:
"Представляет изменяемую строку символов. Этот класс не может быть унаследован."
Что произойдет, если вы объедините неизменные строки много раз? Нагрузка использования памяти для строк без ссылок? Или просто медленно?
Руди
13
@Rudie - оба. Каждая конкатенация создает новый объект String и копирует все символы обеих входных строк. Приводит к O(N^2)поведению ...
Стивен С.
@StephenC объяснил с ключевыми словами.
Кент Ляу
6
если вам приходится многократно изменять строку, например, несколько конкатенаций, тогда используйте StringBuilder ... Это полностью очистило мой разум, спасибо ...
katmanco
45
Объект является изменяемым, если однажды созданный объект может быть изменен путем вызова различных операций с ним, в противном случае он является неизменным.
Неизменная Строка
В C # (и .NET) строка представлена классом System.String. stringКлючевым словом является псевдонимом для этого класса.
Класс System.String является неизменным, т.е. после создания его состояние не может быть изменено .
Таким образом , все операции вы выполняете на строке , как Substring, Remove, Replace, конкатенации с помощью оператора «+» и т.д. создаст новую строку и вернуть его.
Если вы хотите иметь строку, которую хотите часто изменять, вы можете использовать StringBuilderкласс. Операции над StringBuilderэкземпляром изменят тот же объект .
Все stringобъекты неизменны в C #. stringСозданные объекты класса никогда не могут представлять ничего, кроме того, с которым они были созданы. Все операции, которые, кажется, «изменяют» строку, вместо этого производят новую. Это неэффективно с памятью, но чрезвычайно полезно для уверенности в том, что строка не изменит форму под вами - потому что, пока вы не измените свою ссылку, строка, на которую вы ссылаетесь, никогда не изменится.
У изменчивого объекта, напротив, есть поля данных, которые можно изменить. Один или несколько его методов изменят содержимое объекта, или у него есть свойство, которое при записи изменяет значение объекта.
Если у вас есть изменяемый объект, наиболее похожий на String, StringBufferвы должны сделать его копию, если хотите быть абсолютно уверенным, что он не изменится из-под вас. Вот почему изменяемые объекты опасны для использования в качестве ключей в любой форме Dictionaryили для установки - сами объекты могут измениться, и структура данных не сможет узнать, что приведет к повреждению данных, что в конечном итоге приведет к сбою вашей программы.
Тем не менее, вы можете изменить его содержимое, так что это намного, намного более эффективно использует память, чем создание полной копии, потому что вы хотели изменить один символ или что-то подобное.
Как правило, правильнее всего использовать изменяемые объекты при создании чего-либо и неизменные объекты после завершения работы. Конечно, это относится к объектам, которые имеют неизменные формы; большинство коллекций этого не делают. Часто бывает полезно предоставлять формы коллекций только для чтения, что эквивалентно неизменяемости при отправке внутреннего состояния вашей коллекции в другие контексты - в противном случае что-то может принять это возвращаемое значение, что-то с ним сделать и испортить вашу данные.
В .NET System.String (иначе строка) является неизменным объектом. Это означает, что когда вы создаете объект, вы не можете изменить его значение впоследствии. Вы можете воссоздать только неизменный объект.
System.Text.StringBuilder является изменяемым эквивалентом System.String, и вы можете изменить его значение
Создает следующий MSIL: Если вы исследуете код. Вы увидите, что всякий раз, когда вы изменяете объект System.String, вы фактически создаете новый. Но в System.Text.StringBuilder, когда вы изменяете значение текста, вы не воссоздаете объект.
Ммм ... этот дизассемблированный код показывает только то, что присваиваются указатели и вызываются методы. Это (почти) не имеет ничего общего с изменчивым и неизменным. (Это ускользает от меня, почему некоторые люди думают, что дизассемблирование некоторого нерелевантного примера кода поможет людям понять такие вещи. Для начала, большинство программистов не бегло владеют кодом CLI.)
Стивен С.
6
Строки являются изменяемыми, потому что .NET используют пул строк за сценой. Это значит :
string name ="My Country";string name2 ="My Country";
И имя, и имя2 ссылаются на одну и ту же область памяти из пула строк. Теперь предположим, что вы хотите изменить name2 на:
name2 ="My Loving Country";
Он будет искать в строковом пуле строку «Моя любящая страна», если найден, вы получите ссылку на нее, в мудром пуле будет создана новая мудрая строка «Моя любящая страна», а name2 получит ссылку на нее. Но весь этот процесс « Моя страна » не изменился, потому что другая переменная, такая как name , все еще использует его. И это причина, почему строки являются НЕМЕРТНЫМИ .
StringBuilder работает по-другому и не использует пул строк. Когда мы создаем любой экземпляр StringBuilder:
var address =newStringBuilder(500);
Он выделяет кусок памяти размером 500 байт для этого экземпляра, и все операции просто изменяют эту область памяти, и эта память не используется совместно с любым другим объектом. И это причина , почему StringBuilder является Мутабельном .
Нет, на самом деле. Класс String является изменяемым.
unsafe{string foo =string.Copy("I am immutable.");fixed(char* pChar = foo){char* pFoo = pChar;
pFoo[5]=' ';
pFoo[6]=' ';}Console.WriteLine(foo);// "I am mutable."}
Такая логика выполняется все время в классах String и StringBuilder. Они просто выделяют новую строку каждый раз, когда вы вызываете Concat, Substring и т. Д., И используете арифметику указателей для копирования в новую строку. Струны просто не изменяются сами по себе, поэтому их считают «неизменяемыми».
Кстати, не пытайтесь делать это с помощью строковых литералов, иначе вы испортите вашу программу:
string bar ="I am a string.";fixed(char* pChar = bar){char* pBar = pChar;
pBar[2]=' ';}string baz ="I am a string.";Console.WriteLine(baz);// "I m a string."
Это потому, что строковые литералы интернированы в настольном .NET Framework; другими словами, barи bazуказывают на точно такую же строку, поэтому изменение одного приведет к изменению другого. Это все прекрасно, но если вы используете неуправляемую платформу, такую как WinRT, в которой отсутствует интернирование строк.
Ну да. Если вы нарушаете правила, взламывая открытые абстракции, которые должны быть закрыты, то почти ничто не является неизменным. Вы можете делать аналогичные вещи в Java, используя неприятное отражение ... но JLS утверждает, что поведение, которое вы получаете, не определено.
Стивен С.
2
Для пояснения, в C # (или в целом .NET) нет такой вещи, как изменяемая строка. Другие языки поддерживают изменяемые строки (строки, которые могут изменяться), а платформа .NET - нет.
Таким образом, правильный ответ на ваш вопрос - ВСЕ строки неизменны в C #.
Строка имеет особое значение. Строковое ключевое слово "string" - это просто ярлык для объекта, созданного из класса System.String. Все объекты, созданные из строкового класса, ВСЕГДА неизменны.
Если вам нужно изменяемое представление текста, вам нужно использовать другой класс, например StringBuilder. StringBuilder позволяет итеративно создавать коллекцию «слов», а затем преобразовывать ее в строку (снова неизменяемую).
Значение данных не может быть изменено. Примечание. Значение переменной может быть изменено, но исходное значение неизменяемых данных было отброшено, а новое значение данных было создано в памяти.
Краткий ответ: String является неизменным - тогда как StringBuilder является изменяемым.
Что это значит ? Вики говорит: В объектно-ориентированном виде неизменный объект - это объект, состояние которого нельзя изменить после его создания. Это отличается от изменчивого объекта, который можно изменить после его создания.
Из документации класса StringBuilder:
Объект String является неизменным. Каждый раз, когда вы используете один из методов в классе System.String, вы создаете новый строковый объект в памяти, который требует нового выделения пространства для этого нового объекта.
В ситуациях, когда необходимо выполнить повторные изменения строки, накладные расходы, связанные с созданием нового объекта String, могут быть дорогостоящими.
Класс System.Text.StringBuilder может использоваться, когда вы хотите изменить строку без создания нового объекта. Например, использование класса StringBuilder может повысить производительность при объединении множества строк в цикле.
Вот пример для неизменной строки и строителя изменяемой строки
Console.WriteLine("Mutable String Builder");Console.WriteLine("....................................");Console.WriteLine();StringBuilder sb =newStringBuilder("Very Good Morning");Console.WriteLine(sb.ToString());
sb.Remove(0,5);Console.WriteLine(sb.ToString());Console.WriteLine();Console.WriteLine("Immutable String");Console.WriteLine("....................................");Console.WriteLine();string s ="Very Good Morning";Console.WriteLine(s);
s.Substring(0,5);Console.WriteLine(s);Console.ReadLine();
Было бы очень хорошо, если бы вы могли предоставить вывод @Gokul :)
Рой Ли
Подстрока не меняет базовое значение. Он только возвращает значение.
Кай
@ А почему? потому что строки неизменяемы :)
LuckyLikey
Ваш двухстрочный код -: s.Substring (0, 5); ЕЫпе (ы); Здесь s.substring () не меняет s. этот пример не показывает, является ли строка неизменной.
Дхананджай
0
Строка в C # неизменна. Если вы объединяете его с какой-либо строкой, вы фактически создаете новую строку, то есть новый строковый объект! Но StringBuilder создает изменяемую строку.
StringBuilder - лучший вариант для конкатенации огромной строки данных, поскольку StringBuilder является изменяемым строковым типом, а объект StringBuilder является неизменяемым типом, то есть StringBuilder никогда не создает новый экземпляр объекта во время конкататации строки.
Если мы используем строку вместо StringBuilder для достижения конкатенации, то он будет каждый раз создавать новый экземпляр в памяти.
Ответы:
Изменчивые и неизменные - это английские слова, означающие «может измениться» и «не может измениться» соответственно. Значение слов одинаково в контексте ИТ; т.е.
Значения этих слов в C # / .NET такие же, как и в других языках программирования / средах, хотя (очевидно) имена типов могут отличаться, как и другие детали.
Для записи:
String
является стандартным неизменяемым строковым типом C # / .NetStringBuilder
стандартный тип изменяемой строки C # / .NetЧтобы «внести изменения» в строку, представленную как C #
String
, вы фактически создаете новыйString
объект. ОригиналString
не изменился ... потому что он неизменен.В большинстве случаев это лучше использовать,
String
потому что это более легкая причина для них; Например, вам не нужно учитывать возможность того, что какой-то другой поток может «изменить мою строку». Однако, когда вам нужно создать или изменить строку, используя последовательность операций, может быть более эффективно использовать aStringBuilder
.И, наконец, для тех людей, которые утверждают, что a
StringBuilder
не является строкой, потому что она не является неизменной, документация Microsoft описываетStringBuilder
так:источник
String
неизменент.е. строки не могут быть изменены. Когда вы изменяете строку (например, добавляя ее), вы фактически создаете новую строку.
Но
StringBuilder
не является неизменным (скорее, оно изменчиво)так что если вам нужно многократно изменять строку, например, несколько конкатенаций, используйте
StringBuilder
.источник
O(N^2)
поведению ...Объект является изменяемым, если однажды созданный объект может быть изменен путем вызова различных операций с ним, в противном случае он является неизменным.
Неизменная Строка
В C # (и .NET) строка представлена классом System.String.
string
Ключевым словом является псевдонимом для этого класса.Класс System.String является неизменным, т.е. после создания его состояние не может быть изменено .
Таким образом , все операции вы выполняете на строке , как
Substring
,Remove
,Replace
, конкатенации с помощью оператора «+» и т.д. создаст новую строку и вернуть его.Смотрите следующую программу для демонстрации -
Это выведет «string» и «mystring» соответственно.
Для преимуществ неизменности и почему строка неизменна проверка Почему .NET Строка неизмененна? ,
Mutable String
Если вы хотите иметь строку, которую хотите часто изменять, вы можете использовать
StringBuilder
класс. Операции надStringBuilder
экземпляром изменят тот же объект .Для получения более подробной консультации по когда использовать
StringBuilder
смотрите Когда использовать StringBuilder? ,источник
Все
string
объекты неизменны в C #.string
Созданные объекты класса никогда не могут представлять ничего, кроме того, с которым они были созданы. Все операции, которые, кажется, «изменяют» строку, вместо этого производят новую. Это неэффективно с памятью, но чрезвычайно полезно для уверенности в том, что строка не изменит форму под вами - потому что, пока вы не измените свою ссылку, строка, на которую вы ссылаетесь, никогда не изменится.У изменчивого объекта, напротив, есть поля данных, которые можно изменить. Один или несколько его методов изменят содержимое объекта, или у него есть свойство, которое при записи изменяет значение объекта.
Если у вас есть изменяемый объект, наиболее похожий на String,
StringBuffer
вы должны сделать его копию, если хотите быть абсолютно уверенным, что он не изменится из-под вас. Вот почему изменяемые объекты опасны для использования в качестве ключей в любой формеDictionary
или для установки - сами объекты могут измениться, и структура данных не сможет узнать, что приведет к повреждению данных, что в конечном итоге приведет к сбою вашей программы.Тем не менее, вы можете изменить его содержимое, так что это намного, намного более эффективно использует память, чем создание полной копии, потому что вы хотели изменить один символ или что-то подобное.
Как правило, правильнее всего использовать изменяемые объекты при создании чего-либо и неизменные объекты после завершения работы. Конечно, это относится к объектам, которые имеют неизменные формы; большинство коллекций этого не делают. Часто бывает полезно предоставлять формы коллекций только для чтения, что эквивалентно неизменяемости при отправке внутреннего состояния вашей коллекции в другие контексты - в противном случае что-то может принять это возвращаемое значение, что-то с ним сделать и испортить вашу данные.
источник
Неизменный :
Когда вы выполняете какую-либо операцию над объектом, он создает новый объект, следовательно, состояние не может быть изменено, как в случае строки.
изменчивый
Когда вы выполняете какую-либо операцию над объектом, сам объект не изменял созданный новый объект, как в случае StringBuilder
источник
В .NET System.String (иначе строка) является неизменным объектом. Это означает, что когда вы создаете объект, вы не можете изменить его значение впоследствии. Вы можете воссоздать только неизменный объект.
System.Text.StringBuilder является изменяемым эквивалентом System.String, и вы можете изменить его значение
Например:
Создает следующий MSIL: Если вы исследуете код. Вы увидите, что всякий раз, когда вы изменяете объект System.String, вы фактически создаете новый. Но в System.Text.StringBuilder, когда вы изменяете значение текста, вы не воссоздаете объект.
источник
Строки являются изменяемыми, потому что .NET используют пул строк за сценой. Это значит :
И имя, и имя2 ссылаются на одну и ту же область памяти из пула строк. Теперь предположим, что вы хотите изменить name2 на:
Он будет искать в строковом пуле строку «Моя любящая страна», если найден, вы получите ссылку на нее, в мудром пуле будет создана новая мудрая строка «Моя любящая страна», а name2 получит ссылку на нее. Но весь этот процесс « Моя страна » не изменился, потому что другая переменная, такая как name , все еще использует его. И это причина, почему строки являются НЕМЕРТНЫМИ .
StringBuilder работает по-другому и не использует пул строк. Когда мы создаем любой экземпляр StringBuilder:
Он выделяет кусок памяти размером 500 байт для этого экземпляра, и все операции просто изменяют эту область памяти, и эта память не используется совместно с любым другим объектом. И это причина , почему StringBuilder является Мутабельном .
Надеюсь, это поможет.
источник
Нет, на самом деле. Класс String является изменяемым.
Такая логика выполняется все время в классах String и StringBuilder. Они просто выделяют новую строку каждый раз, когда вы вызываете Concat, Substring и т. Д., И используете арифметику указателей для копирования в новую строку. Струны просто не изменяются сами по себе, поэтому их считают «неизменяемыми».
Кстати, не пытайтесь делать это с помощью строковых литералов, иначе вы испортите вашу программу:
Это потому, что строковые литералы интернированы в настольном .NET Framework; другими словами,
bar
иbaz
указывают на точно такую же строку, поэтому изменение одного приведет к изменению другого. Это все прекрасно, но если вы используете неуправляемую платформу, такую как WinRT, в которой отсутствует интернирование строк.источник
Для пояснения, в C # (или в целом .NET) нет такой вещи, как изменяемая строка. Другие языки поддерживают изменяемые строки (строки, которые могут изменяться), а платформа .NET - нет.
Таким образом, правильный ответ на ваш вопрос - ВСЕ строки неизменны в C #.
Строка имеет особое значение. Строковое ключевое слово "string" - это просто ярлык для объекта, созданного из класса System.String. Все объекты, созданные из строкового класса, ВСЕГДА неизменны.
Если вам нужно изменяемое представление текста, вам нужно использовать другой класс, например StringBuilder. StringBuilder позволяет итеративно создавать коллекцию «слов», а затем преобразовывать ее в строку (снова неизменяемую).
источник
StringBuilder
противоречит этому: см. Msdn.microsoft.com/en-us/library/…Значение данных не может быть изменено. Примечание. Значение переменной может быть изменено, но исходное значение неизменяемых данных было отброшено, а новое значение данных было создано в памяти.
источник
в деталях реализации.
System.String в CLR2 является изменяемой. StringBuilder.Append, вызывающий String.AppendInplace (закрытый метод)
System.String в CLR4 является неизменным. StringBuilder имеет массив Char с чанкингом.
источник
От http://yassershaikh.com/what-is-the-difference-between-strings-and-stringbuilder-in-c-net/
Краткий ответ: String является неизменным - тогда как StringBuilder является изменяемым.
Что это значит ? Вики говорит: В объектно-ориентированном виде неизменный объект - это объект, состояние которого нельзя изменить после его создания. Это отличается от изменчивого объекта, который можно изменить после его создания.
Из документации класса StringBuilder:
Объект String является неизменным. Каждый раз, когда вы используете один из методов в классе System.String, вы создаете новый строковый объект в памяти, который требует нового выделения пространства для этого нового объекта.
В ситуациях, когда необходимо выполнить повторные изменения строки, накладные расходы, связанные с созданием нового объекта String, могут быть дорогостоящими.
Класс System.Text.StringBuilder может использоваться, когда вы хотите изменить строку без создания нового объекта. Например, использование класса StringBuilder может повысить производительность при объединении множества строк в цикле.
источник
Вот пример для неизменной строки и строителя изменяемой строки
источник
Строка в C # неизменна. Если вы объединяете его с какой-либо строкой, вы фактически создаете новую строку, то есть новый строковый объект! Но StringBuilder создает изменяемую строку.
источник
StringBuilder - лучший вариант для конкатенации огромной строки данных, поскольку StringBuilder является изменяемым строковым типом, а объект StringBuilder является неизменяемым типом, то есть StringBuilder никогда не создает новый экземпляр объекта во время конкататации строки.
Если мы используем строку вместо StringBuilder для достижения конкатенации, то он будет каждый раз создавать новый экземпляр в памяти.
источник