有谁知道为什么这个嵌套字典中的项目似乎是链接在一起的?

Does anyone know why the items within this nested dictionary seem to be linked together?

提问人:when-cowz-fly 提问时间:8/3/2023 最后编辑:when-cowz-fly 更新时间:8/4/2023 访问量:29

问:

在下面的代码中,当我遍历字典中第一个或第二个字典中的浮点数组的值并修改任何值时,它会修改另一个子字典中的相应值。例如,如果我运行此代码,就好像计算机甚至在到达代码的那部分之前就运行了,从而在结束时导致不必要的加倍效果。agg_dict[report_type][0][unit_type_key][j] += 1agg_dict[report_type][1][unit_category_key][j] += 1;

这是有错误的主要函数:

private void add_values_to_dict(Dictionary<string, Dictionary<string, float[]>[]> agg_dict, float[] hour_columns, string report_type, string region, string unit_type, string unit_category)
{
    try
    {
        if (agg_dict.ContainsKey(report_type))
        {
            string unit_type_key = region + "," + unit_type;
            string unit_category_key = region + "," + unit_category;

            if (agg_dict[report_type][0].ContainsKey(unit_type_key))
            {
                for (int j = 0; j < agg_dict[report_type][0][unit_type_key].Length; j++)
                {
                    agg_dict[report_type][0][unit_type_key][j] += (float)Convert.ToDouble(hour_columns[j]);
                }
            }
            else
            {
                agg_dict[report_type][0].Add(unit_type_key, hour_columns);
            }

            if (agg_dict[report_type][1].ContainsKey(unit_category_key))
            {
                for (int j = 0; j < agg_dict[report_type][1][unit_category_key].Length; j++)
                {
                    agg_dict[report_type][1][unit_category_key][j] += (float)Convert.ToDouble(hour_columns[j]);
                }
            }
            else
            {
                agg_dict[report_type][1].Add(unit_category_key, hour_columns);
            }

        }
        else
        {
            Dictionary<string, float[]>[] dict_array = new Dictionary<string, float[]>[2]; // 0 == unit type 1 == unit category
            dict_array[0] = new Dictionary<string, float[]>();
            dict_array[1] = new Dictionary<string, float[]>();
            dict_array[0].Add(region + "," + unit_type, hour_columns);
            float[] hour_columns_copy = hour_columns;
            dict_array[1].Add(region + "," + unit_category, hour_columns_copy);
            agg_dict.Add(report_type, dict_array);
        }
    }
    catch (Exception ex)
    {
        Logger.log(ex);
    }
}

这是创建hour_columns数组的函数:

public void make_hours_array(string[] split_array, ref float[] hour_columns)
{
    try
    {
        hour_columns[0] = (float)Convert.ToDouble(split_array[max_capacity_index]);
        hour_columns[1] = (float)Convert.ToDouble(split_array[min_capacity_index]);

        int cnt = 2;
        for (int i = static_col_len; i < split_array.Length; i++)
        {
            //check to account for non number entries
            if (!Char.IsDigit(split_array[i][0]))
            {
                int looper = 0;
                bool has_num = false;
                foreach (char c in split_array[i])
                {
                    if (c == '-')
                    {
                        has_num = true;
                        looper++;
                        break;
                    }
                    looper++;
                }
                if (has_num)
                {
                    string finding_num = split_array[i].Trim();
                    string num = "";
                    char new_c = finding_num[looper];
                    while (!Char.IsDigit(new_c) && looper < finding_num.Length)
                    {
                        looper++;
                        new_c = finding_num[looper];
                    }
                    while (looper < finding_num.Length)
                    {
                        new_c = finding_num[looper];
                        num += new_c;
                        looper++;
                    }
                    hour_columns[cnt] = (float)Convert.ToDouble(num);
                }
                else
                {
                    hour_columns[cnt] = 0.0f;
                }
            }
            else //else copies the string array into float array
            {
                hour_columns[cnt] = (float)Convert.ToDouble(split_array[i]);
            }
            cnt++;
        }
    }
    catch(Exception ex)
    {
        Logger.log(ex);
    }
            
}

这是两个函数被调用:

make_hours_array(row_split_into_array, ref hour_columns);

add_values_to_dict(agg_dict, hour_columns, report_type, region,unit_type, unit_category);

我知道的一件事是,第一个函数中的浮点转换是多余的。我本来想在上次错误修复尝试之前删除它,但忘记了,所以我保留了它,以保持我遇到最新错误时运行的内容。我想,虽然是多余的,但它不会导致我遇到的这个链接问题。

我最初是通过引用传递hours_column和split_array,并认为这就是导致问题的原因。但是我删除了引用,这些值似乎仍然是链接的。我假设它与创建子词典的时间有关。

C# 字典 嵌套

评论

0赞 Charlieface 8/4/2023
老实说,这段代码需要一个合适的对象模型。 类似的东西。还有一些正则表达式将字符串解析为数字。我不知道你为什么使用浮点数,这可能是一个更好的主意。class Report { string report_type; List<float> unit_type; List<float> unit_category; }decimal

答:

0赞 AndrewS 8/3/2023 #1

数组是引用类型(不是值类型),因此以下行不会创建数组的副本 - 它只是对同一数组实例的另一个引用:

float[] hour_columns_copy = hour_columns;

也许使用 Clone 方法创建数组的浅拷贝。

评论

0赞 when-cowz-fly 8/3/2023
克隆方法不起作用。我尝试使用复制方法,但也没有用。
0赞 when-cowz-fly 8/4/2023 #2

我通过将嵌套字典分成两个字典并更改make_hours_array以不使用“ref”关键字传递,然后从头开始初始化两个不同的hour_colmns数组并为每个字典传递一个单独的数组来修复它。