【问题标题】:List with string array (List<string[]>)带有字符串数组的列表 (List<string[]>)
【发布时间】:2013-06-14 13:36:05
【问题描述】:

我有一个奇怪的问题,我的所有字符串数组在列表中都有相同的值。 这是我的代码:

List<string[]> map_data = new List<string[]>();
string[] map_data_array = new string[11];

for(int i = 0; i < 2000; i++)
{
    map_data_array = PopulateDataFromFile(); // it returns different data every call
    map_data.Add(map_data_array); // store to List
}

map_data_array 总是有不同的数据,我已经通过将断点放在那里进行了验证并检查了它。

问题是map_data 的所有元素的值都相同。而这个值就是函数PopulateDataFromFile在i为1999时得到的数据。

我做错了什么? :/

【问题讨论】:

  • 同时发布PopulateDataFromFile()的代码
  • 在即时窗口中试试这个map_data[0] == map_data[1999] 如果它返回true 你添加相同的数组2000 次(即PopulateDataFromFile() 返回相同的数组如果它返回false 然后@987654329 @ 每次返回一个新数组,但内容相同
  • @Golgauth 请不要在标题中添加标签,它是出于某种目的而被删除的。也不要使用内联代码来标记帖子中的每个关键字,这会产生过多的“噪音”。
  • 在调试时再检查一件事 - 在第二次迭代中,当您看到 map_data_array 返回了不同的值时,请检查 map_data[0] 是否也具有相同的值。这意味着您的代码在某处更新了相同的引用。
  • @ShadowWizard 好的,注意内联代码,我保证不会再这样做了;-) 但我从未更改过标题...

标签: c# arrays string list


【解决方案1】:

仅当您将相同的数组放入列表时才会发生这种情况。由于您没有将代码提供给PopulateDataFromFile,我们只能猜测会发生什么。确保该函数每次返回一个使用new 创建的单独数组。

【讨论】:

  • 谢谢,我在“全局”范围内声明了“map_data_array”。
  • 但是为什么会这样呢?列表是否真的“链接”了对象而不是保存/复制该对象拥有的数据?
  • @tilenslo 这是因为PopulateDataFromFile(); 可能在每次迭代中返回相同的数据。
  • 是的!这是一个很好的综合,关于我们这里的少数情报。
  • @svick 嗯`所以,如果您查看返回后立即返回的数组 PopulateDataFromFile(),看起来它每次都返回不同的数据。`为什么我很难相信这一点?由于我们没有该方法的具体代码,我们只能推测它的实现。
【解决方案2】:

您需要分块处理数据,因为PopulateDataFromFile(); 看起来会一次性返回其所有数据(或尽可能多地返回数组可以容纳的数据)。使用扩展方法,您可以执行以下操作:-

List<string[]> map_data = new List<string[]>();
foreach (var batch in PopulateDataFromFile().Batch(11))
{
       map_data.Add((batch.ToArray());
}

扩展方法:-

public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items, int batchSize)
{
     return items.Select((item, inx) => new { item, inx })
                 .GroupBy(x => x.inx / batchSize)
                 .Select(g => g.Select(x => x.item));
}

【讨论】:

  • 我真的不明白分块处理会有什么帮助。为什么是11?为什么不是 10000000?
  • 可能与:string[] map_data_array = new string[11];... 在我看来 PopulateDataFromFile(); 可能会返回所有内容,但请随意不同意 :)
  • 对,我没有意识到这一点。但这意味着您的代码甚至更少有意义,因为它总是会返回一个批次。
  • ???为何如此?考虑 2000 的集合大小。它会在哪个星球上返回单个批次?
  • 我假设 PopulateDataFromFile() 总是返回一个 11 元素的数组。但无论如何,我仍然看不到批处理数据可以解决问题的任何情况。
【解决方案3】:

PopulateDataFromFile() 返回一个具有相同值的字符串数组。

【讨论】:

  • 问题的说法不同:“map_data_array 总是有不同的数据”。
【解决方案4】:

在循环中,每次您只需更改 map_data_array 的地址,这就是为什么值总是会更改为从方法调用获得的较新数据的原因。每次重新初始化字符串数组都会有所帮助。它应该看起来像这样

    for(int i = 0; i < 2000; i++)
    {
         string[] map_data_array = PopulateDataFromFile(); // it returns different data every call
         map_data.Add(map_data_array); // store to List
    } 

或者如果它让你感到困惑,你可以通过

让它变得简单
    for(int i = 0; i < 2000; i++)
    {             
         map_data.Add(PopulateDataFromFile()); // store to List
    } 

【讨论】:

  • 我不明白这里的答案......这与OP所做的基本相同。
  • 抱歉,打错了。只有函数的返回值决定了列表中存储的内容,无论您将其临时存储在哪个变量中(只要您不进行复制)。
  • 你是说如果你在循环外声明map_data_array然后改变它,列表中的值也会改变吗?这当然不是真的。
  • 这不会改变任何事情。声明不确定存储位置,只有new 确定。
  • 是的,您必须确保方法(PopulateDataFromFile)的返回值始终是一个新对象,而不是仅仅更改现有对象。
猜你喜欢
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
相关资源
最近更新 更多