Home > Back-end >  Using struct in dictionary as a value
Using struct in dictionary as a value

Time:10-16

Hi I have a struct and dictionary as below and I'm trying to add it as a custom value like

public struct data_inv
{
    //protected static int p;
    public float inventory;
    public  float supply;
    public  float demand;
};

public static IDictionary<int, data_inv> inv_stored = new Dictionary<int, data_inv>();

and I have tried to add value to dictionary but when I try to add a value like inv_stored[1].demand = 4; its gives System.Collections.Generic.KeyNotFoundException: 'The given key was not present in the Dictionary.' exception. I'm new to coding, could any explain what im doing wrong

CodePudding user response:

If you want to use a struct instead of a class, write this instead of inv_stored[1].demand = 4 (updated based on comments):

public struct data_inv
{
    public float Inventory;
    public float Supply;
    public float Demand;
    
    public data_inv(int demand)
    {
        Inventory = 0;
        Supply = 0;
        Demand = demand;
    }
};

// ....
    IDictionary<int, data_inv> inv_stored = new Dictionary<int, data_inv>();

    data_inv myData = new data_inv(4);
    inv_stored.Add(1, myData);

This is a way to add keyValue to a Dictionary.

CodePudding user response:

data_inv shouldn't be a struct. It's mutable, and structs shouldn't be mutable, it's not representing a single value. You should make it a class instead.

public class data_inv
{
    //protected static int p;
    public float inventory;
    public  float supply;
    public  float demand;

};

Implementation:

// Add new item into dictionary
inv_stored.Add(1, new data_inv()
{
    inventory = 20,
    supply = 10,
    demand = 5
});

Console.WriteLine(inv_stored[1].demand); // 5

inv_stored[1].demand = 4;
Console.WriteLine(inv_stored[1].demand); // 4

Edit:
Print all elements each in one line:

foreach (var kvp in inv_stored)
{
    Console.Write("bucket:{0} ", kvp.Key);
    Console.Write("inventory:{0}, ", kvp.Value.inventory);
    Console.Write("supply:{0}, ", kvp.Value.supply);
    Console.WriteLine("demand:{0}", kvp.Value.demand);
}

Example output:

bucket:1 inventory:20, supply:10, demand:4
bucket:2 inventory:16, supply:9, demand:7

CodePudding user response:

There's multiple problems with your code.

First, you can create a new record in a dictionary by doing something like dict[key] = value;. However, you can not do dict[key].field = value;. The setter can be used with non-existent keys, the getter can't.

Second, while you can use structs as values in a dictionary, you cannot set their fields directly. Structs use value-type semantics by default (i.e. whenever you don't explicitly use ref or take a pointer), so any change you made this way would be done to a copy of the struct, not the actual value in the dictionary. You can use something like this:

var val = dict[key];
val.field = newFieldValue;
dict[key] = val;

Third, it's generally considered bad practice to use mutable structs, exactly because of these complications. Mutable structs only have place in highly optimised code and native interop, and they need to be carefully tested and monitored. Heck, even many automated refactorings can break code with mutable structs.

  •  Tags:  
  • c#
  • Related