2017-01-07 34 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

相关问题