每个新密钥都会重置C#Hashtable值

时间:2014-05-11 13:22:15

标签: c# collections hashtable

我有一个返回Hashtable的函数。 var dt从数据库中获取一堆RevenueGroupID和ProductID,它们以1对多的结构一起映射。例如:

RevenueGroupID ProductID
1                 312
1                 313
1                 315
2                 317
2                 319
3                 401
3                 410
3                 411
3                 415

这两个数字的组合始终是唯一的 - 没有重复。该函数构建键值对的Hashtable字典,其中键始终为RevenueGroupID,值为该RevenueGroupID的所有ProductID的List<int>。问题是:每次添加键值对时,所有先前的键值对都会被当前键值对覆盖。所以最后,所有键值对都与最后一对相同。我已逐步完成代码并验证每个键值对是正确且唯一的。我看不出任何重置的原因。我怀疑地看着“productIDs.Clear();”,但是我不明白为什么会搞乱哈希表。

public static Hashtable GetAllProductIDsInAllRevenueGroups()
{
    var productIDs = new List<int>();
    var ht = new Hashtable();

    string sql = @" {my sql here}";

    var dt = Utilities.GetDataTableForQuery(sql, null);

    int counter = 0;
    int revenueGroupID = 0;
    int lastRevenueGroupID = 0;

    foreach (DataRow row in dt.Rows)
    {
        revenueGroupID = Utilities.SafeInt(row["RevenueGroupID"]);
        int productID = Utilities.SafeInt(row["ProductID"]);

        if (revenueGroupID != lastRevenueGroupID && counter > 0)
        {
            ht.Add(lastRevenueGroupID, productIDs);
            productIDs.Clear();
        }

        productIDs.Add(productID);
        lastRevenueGroupID = revenueGroupID;
        counter++;
    }

    ht.Add(lastRevenueGroupID, productIDs);
    return ht;
}

2 个答案:

答案 0 :(得分:2)

这是因为您继续将productIDs列表添加到哈希表中而不进行复制,然后清除内容:

ht.Add(lastRevenueGroupID, productIDs);
productIDs.Clear(); // This removes all entries from the item stored at the lastRevenueGroupID key

这意味着一遍又一遍地添加相同的对象,因此最终会得到包含最后一个条目内容的列表的多个副本。

一个简单的解决方法是在将新列表添加到哈希表之前创建一个新列表,如下所示:

ht.Add(lastRevenueGroupID, productIDs.ToList());
productIDs.Clear();

答案 1 :(得分:0)

问题是您只使用一个列表而不是为每个项目创建新列表。将列表添加到哈希表并不会创建列表的副本,它只是添加引用。清除列表后,您将清除哈希表中所有以前添加的项目的列表,因为它们都是相同的列表。

您可以创建新列表,并在启动新组时添加到哈希表。当您保留对列表的引用时,您可以在哈希表中放置数字后继续添加数字:

public static Hashtable GetAllProductIDsInAllRevenueGroups()
{
    var productIDs;
    var ht = new Hashtable();

    string sql = @" {my sql here}";

    var dt = Utilities.GetDataTableForQuery(sql, null);

    int counter = 0;
    int revenueGroupID = 0;
    int lastRevenueGroupID = 0;

    foreach (DataRow row in dt.Rows)
    {
        revenueGroupID = Utilities.SafeInt(row["RevenueGroupID"]);
        int productID = Utilities.SafeInt(row["ProductID"]);

        if (counter == 0 || revenueGroupID != lastRevenueGroupID)
        {
            productIDs = new List<int>();
            ht.Add(revenueGroupID, productIDs);
        }

        productIDs.Add(productID);
        lastRevenueGroupID = revenueGroupID;
        counter++;
    }

    return ht;
}

注意:请考虑使用严格键入的Dictionary<int, List<int>>代替Hashtable