2017-01-07 11 views
-4

Скажут, у меня есть массив строк от выполнения этого метода SplitКогда и лучший способ сделать точные копии строк в C#

string[] parsed = message.Split(' '); 

И тогда я хочу сохранить определенное значение этого массива в новом строка

string name = parsed[3]; 

Теперь я удалить эту строку из массива, используя метод расширения, этот метод удаляет значение по указанному индексу и сдвигает все назад, чтобы заполнить пробел

parsed = parsed.RemoveAt(3); 

Я знаю, что поскольку строки являются ссылочными типами в C#, моя переменная имени теперь равна null, после небольшого поиска мне сказали, что делать точные копии строк в C# бесполезно. Каков наилучший и правильный способ установки переменной имени в качестве нового экземпляра, чтобы он не удалялся после вызова .RemoveAt()?

EDIT:

Это лучший способ, который я нашел до сих пор

string name = new string(parsed[3].ToCharArray()); 

Другой способ, предложенный Willy David Jr

parsed = parsed.Where((source, index) => index != 3).ToArray(); 

EDIT 2:

Пожалуйста, игнорировать этот вопрос и прочитал одобренный ответ, я неправильно понял, как работают ссылочные типы.

+1

Просто не беспокойтесь об этом. C# имеет автоматическую сборку мусора. Пусть коллекционер выполнит свою работу, и вы можете беспокоиться о чем-то другом. Ваше убеждение, что уплотнение массива меняет значение вашей локальной переменной, является ложным. –

+1

Что заставляет вас думать, что 'name' будет null после удаления элемента из массива? 'name' не заботится о том, что происходит с массивом - он все еще содержит ссылку на строку, которую вы ему назначили. –

+0

Ну, тогда я должен неправильно понимать, как работают ссылки, строка будет существовать даже после того, как я удалю ее из массива? насколько я знаю, это будет сбор мусора, потому что никакие другие ссылки не будут указывать на него – user7386753

ответ

1

Вы не понимаете, как работают ссылочные типы. Удаление объекта из массива никак не изменяет этот объект - это просто означает, что массив больше не содержит ссылку .

Вы можете проверить это самостоятельно. Запустите код, который вы включили в отладчик (или консольное приложение), а затем просмотрите (или распечатайте) значение name в конце.

Дело в том, что может обмануть вас с ссылочными типами, когда есть две переменные (или массивы или что-то еще), которые содержат ссылку на один и тот же объект.В этом случае изменения, внесенные в объект через одну переменную, будут отражаться при обращении к объекту через другую переменную - это тот же объект, но с двумя разными переменными , ссылающийся на. Если вы хотите, чтобы обе переменные ссылались на свою собственную «копию» объекта, вы должны сами создать копию и назначить ее одной из переменных.

Однако в C#, то string тип неизменны, а это означает, что когда-то создается string объект не существует никакого способа изменить этот объект. Поэтому нет причин создавать копию строки. Если есть переменная, которая ссылается на определенную строку, вы можете быть уверены, что никакая другая ссылка не сможет ее изменить из-под вас.

+0

Я вижу, спасибо за ответ. – user7386753

-1

Уверены, что на вашей строке есть RemoveAt? Есть RemoveAt on Collections, но не по строке или массиву строк как таковой.

Вы можете сделать это вместо того, чтобы:

List<string> lstParse = new List<string>(); 

foreach (var i in parsed) 
    { 
     lstParse.Add(i); 
    } 
string name = parsed[3];  
lstParse.RemoveAt(3); 

Чтобы присоединиться снова список и преобразовать его в строку:

string strResult = string.Join(" ", lstParse.ToArray()); 

Если вы действительно хотите удалить индекс без нового списка объектов, игнорирование код, указанный выше, и вы можете сделать это в одной строке:

parsed = parsed.Where((source, index) => index != 3).ToArray(); 
+0

Это мой метод RemoveAt https://hastebin.com/opucotefaz.cs – user7386753

+0

Они упоминают, что они добавили метод расширения. То, что вы делаете, даст то же поведение, что и OP. –

+0

_using метод расширения_? – Badiparmagi

0

Почему вы думаете, что ваш name переменная должна быть нулевой? После удаления из массива он останется нетронутым. Ваш оригинальный код достаточно, чтобы выполнить то, что вы хотите.

+0

Как это нетронуто, если имя просто указывает на строку в parsed [], которая была удалена – user7386753

+1

Она удалена из массива, но переменная 'name' все еще указывает на эту строку. Прочтите об основах C# перед тем, как начать downvoting, пожалуйста. –

+0

Я не спустил вниз сэр, на самом деле у меня недостаточно голосов, чтобы проголосовать за комментарии. Спасибо за ответ – user7386753