[英]Clearing a List<string> removes all values from Dictionary List of Strings, C#
Trying to read a csv file, and take the first word in the stream, throw it in to a dictionary while the following words get added to a list in that dictionary. 尝试读取一个csv文件,并将流中的第一个单词放入字典中,然后将随后的单词添加到该字典中的列表中。
However, I find that (during debugging) when, inside my loop I decide to clear my list, all of the values it had added to the dictionary previously also get cleared. 但是,我发现(在调试过程中)当我决定在循环中清除列表时,先前添加到字典中的所有值也都被清除了。 I guess I am mistaken in assuming it makes a copy of the list, it is actually just referencing that same list?
我猜我以为它是列表的副本是错误的,它实际上只是在引用相同的列表? Should I be creating a new list with every iteration?
我应该在每次迭代时创建一个新列表吗? Code below:
代码如下:
public class TestScript : MonoBehaviour {
// Use this for initialization
void Start() {
Dictionary<string, List<string>> theDatabase = new Dictionary<string, List<string>>();
string word;
string delimStr = ",.:";
char[] delimiter = delimStr.ToCharArray();
List<string> theList = new List<string>();
using (StreamReader reader = new StreamReader("testComma.csv")) {
while (true) {
//Begin reading lines
string line = reader.ReadLine();
if (line == null) {
break;
}
//Begin splitting lines, adding to array.
string[] split2 = line.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
//Loop to hold the first word in the stream
for(int i = 0; i <= 0; i++) {
word = split2[i];
//loop to hold the following words in to list.
for (int y = 1; y < split2.Length; y++) {
theList.Add(split2[y]);
}
//Add word/list combo in to the database
theDatabase.Add(word, theList);
//clear the list.
theList.Clear();
}
}
}
foreach (KeyValuePair<string, List<string>> pair in theDatabase) {
string keys;
List<string> values;
keys = pair.Key;
values = pair.Value;
print(keys + " = " + values);
}
}
}
The bottom foreach loop is just so I can see the results. 最下面的foreach循环就是这样,我可以看到结果。 Also, any critique is welcome in regards to how this is written, as I'm a beginner.
另外,我是初学者,欢迎就其写作方式提出任何批评。
Yes, you're adding the same object to your dictionary. 是的,您要将同一对象添加到字典中。
You can just change : 您可以更改:
theDatabase.Add(word, theList);
To : 至 :
theDatabase.Add(word, theList.ToList());
Method ToList()
makes shallow copy of your List<T>
方法
ToList()
对您的List<T>
进行浅表复制
C# is pass by reference. C#通过引用传递。
So, theList
and the list in your Dictionary
are the same object. 因此,
theList
和Dictionary
中的列表是同一对象。
The simplest solution is to stop clearing your List
and create a new one every time instead: 最简单的解决方案是停止清除
List
,而是每次都创建一个新List
:
for(int i = 0; i <= 0; i++) {
List<string> theList = new List<string>(); // it is in a loop now
word = split2[i];
//loop to hold the following words in to list.
for (int y = 1; y < split2.Length; y++) {
theList.Add(split2[y]);
}
//Add word/list combo in to the database
theDatabase.Add(word, theList);
//clear the list.
//theList.Clear(); - not required anymore
}
It is more readable and clear solution: create a list, insert items, paste a list into the dictionary, continue the iteration. 它是一种更具可读性和清晰的解决方案:创建列表,插入项目,将列表粘贴到字典中,继续迭代。
It is also much more performant since there is no List
clearing - List<T>.Clear()
is a linear operation, which takes O(n)
operations. 由于没有
List
清除,因此它的性能也更高List<T>.Clear()
是线性运算,需要O(n)
运算。
Yes, as everyone says, lists are reference types. 是的,正如大家所说,列表是引用类型。 You need to make a copy to avoid the
.Clear()
clearing all the lists. 您需要进行复制以避免
.Clear()
清除所有列表。
You could always write your code like this: 您总是可以这样编写代码:
void Start()
{
string delimStr = ",.:";
Dictionary<string, List<string>> theDatabase =
File
.ReadAllLines("testComma.csv")
.Select(line => line.Split(delimStr.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
.ToDictionary(x => x[0], x => x.Skip(1).ToList());
/* foreach here */
}
} }
This doesn't have the problem with the list references. 列表引用没有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.