2017-01-07 37 views
-4

比方說,我有一個字符串數組從執行該分割方法當,最好的方法,使字符串的精確副本在C#

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

然後,我要存儲在一個新的數組的一定值串

string name = parsed[3]; 

現在我使用的擴展方法除去從數組該字符串,該方法刪除指定索引處的值和轉移一切回到填充間隙

parsed = parsed.RemoveAt(3); 

我知道,因爲字符串是C#中的引用類型,我的名字變量現在爲空,在搜索了一點之後,我被告知在C#中精確複製字符串是無用的。將name變量設置爲新實例以便它在.RemoveAt()調用後不會被刪除的最好和正確的方法是什麼?

編輯:

這是我迄今發現

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

通過Willy David Jr

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

編輯提出的另一種方式的最佳途徑2:

請忽略此問題並閱讀批准的答案,我誤解了參考類型的工作方式。

+1

不用擔心。 C#具有自動垃圾收集功能。讓收藏家做好工作,你可以擔心別的事情。你相信壓縮數組會改變你的局部變量的值是錯誤的。 –

+1

從數組中刪除元素後,你認爲'name'是什麼? 'name'不關心數組發生了什麼 - 它仍然包含對您分配的字符串的引用。 –

+0

那麼我必須誤解有關引用是如何工作的,即使從數組中刪除它,字符串仍然存在?據我所知,這將是垃圾收集,因爲沒有其他引用將指向它 – user7386753

回答

1

您誤解了引用類型的工作方式。從陣列中移除對象不會以任何方式修改該對象 - 這僅表示該陣列不再包含對象的引用

你可以自己測試一下。運行包含在調試器(或控制檯應用程序)中的代碼,然後在最後查看(或打印出)name的值。

可以這樣的事情引發了你的引用類型,當有兩個變量(或數組或任何)持有對同一對象的引用。在這種情況下,通過一個變量對對象所做的更改將在通過另一個變量訪問對象時反映出來 - 它是同一個對象,但有兩個不同的變量它引用它。如果您希望兩個變量都引用它們自己的對象副本,則必須自己創建一個副本並將其分配給其中一個變量。

然而,在C#中,string類型是不可變的,這意味着一旦一個string對象被創建沒有辦法來改變該對象。所以沒有理由創建一個字符串的副本。如果存在引用特定字符串的變量,則可以確保沒有其他引用可以將它從您的下面更改。

+0

我明白了,謝謝你的回答。 – user7386753

-1

你確定在你的字符串處有RemoveAt嗎?集合上有RemoveAt,但本身不包含字符串或字符串數​​組。

你可以這樣做,而不是:

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

_使用擴展方法_? – Badiparmagi

0

你爲什麼認爲你的name變量應該爲空?從陣列中移除後它將保持不動。您的原始代碼足以實現您的願望。

+0

如果名稱只是指向已解析[]中的字符串,並且已被刪除,它如何不受影響 – user7386753

+1

它從數組中移除,但是'name'變量仍然指向該字符串。請在downvoting之前閱讀C#基礎知識。 –

+0

我沒有低估了先生,實際上我沒有足夠的代表對評論投票。感謝您的回答 – user7386753

相關問題