none
C# - How to see the values in a dictionary RRS feed

  • Question

  • Hi,

    I have a program that saves values in a dictionary and then looks it up again to return the value with the specific key. I added a parameter for the dictionary hard-coded, but VS cannot find it in the dictionary. The error was that VS could not find the requested key in the dictionary.

    De code for adding the parameters:

    public override IDictionary<DParam, Dictionary<int, string>> getDefaultParams()
            {
                IDictionary<DParam, Dictionary<int, string>> defaultparams = new Dictionary<DParam, Dictionary<int, string>>();
    
                defaultparams.Add(new DParam { pluginid = FPlugin.id, type = DParam.EType.value.ToString(), naam = ExampleParams.reset.ToString(), omschrijving = "Reset counters in de PLC", datatype = DParam.EDatatype.@bool.ToString(), adres = "5", ingeschakeld = DParam.EIngeschakeld.niet.ToString(), nietverwijderbaar = true, volgorde = 1, eenheid = "" }, new Dictionary<int, string>());
                defaultparams.Add(new DParam { pluginid = FPlugin.id, type = DParam.EType.value.ToString(), naam = ExampleParams.aantalok.ToString(), omschrijving = "Aantal dozen OK", datatype = DParam.EDatatype.@integer.ToString(), adres = "74", ingeschakeld = DParam.EIngeschakeld.altijd.ToString(), nietverwijderbaar = true, volgorde = 2, eenheid = "stk.", eenheidTellen = "stk." }, new Dictionary<int, string>());
                
                return defaultparams;
            }

    DParam in this case is used for the database (the language is Dutch, so if you need translations please tell me):

    //mogelijke waardes van de eigenschap type.
            public enum EType { value, variable };
            //mogelijke waardes van de eigenschap datatype. deze word ook gebruikt in de tabel Config.
            public enum EDatatype { @string, integer, integer32, @bool, boolDropdown, @double, double1, double2, double3, double4, double5, double6, double7, double8, dropdown };
            //mogelijke waardes van de eigenschap ingeschakeld
            // ReSharper disable UnusedMember.Global
            public enum EIngeschakeld { altijd, niet, tellen, wegen };
            // ReSharper restore UnusedMember.Global
    
            [Indexed]
            public virtual int pluginid { get; set; }
    
            public virtual string type { get; set; }
            public virtual string datatype { get; set; }
            public virtual string eenheid { get; set; }
            public virtual string eenheidTellen { get; set; }
            public virtual string category { get; set; }
            public virtual string adres { get; set; }
            public virtual string naam { get; set; }
            public virtual int volgorde { get; set; }
            public virtual bool zichtbaar { get; set; }
            public virtual bool shortlist { get; set; }
            public virtual string standaardwaarde { get; set; }
            public virtual float? ondergrens { get; set; }
            public virtual float? bovengrens { get; set; }
            public virtual string omschrijving { get; set; }
            public virtual string ingeschakeld { get; set; }
            public virtual int verwijzing { get; set; }
            public virtual bool littleendian { get; set; }
            public virtual bool nietverwijderbaar { get; set; }
    
            //public virtual DPlugin plugin { get; set; } //TODO: nodig voor eager loading.
    
            public static DParam getStringParam(int APluginid, string ANaam, int AVolgorde, string AAdres = "")
            {
                return new DParam()
                {
                    pluginid = APluginid,
                    type = EType.value.ToString(),
                    datatype = EDatatype.@string.ToString(),
                    eenheid = "",
                    eenheidTellen = "",
                    category = "",
                    adres = AAdres,
                    naam = ANaam,
                    volgorde = AVolgorde,
                    zichtbaar = true,
                    shortlist = false,
                    standaardwaarde = "",
                    ondergrens = 0,
                    bovengrens = null,
                    omschrijving = "",
                    ingeschakeld = EIngeschakeld.altijd.ToString(),
                    verwijzing = -1,
                    littleendian = false,
                    nietverwijderbaar = false
                };
            }        
        }

    When I want to look something in the dictionary, I use:

    if (paramList.TryGetValue(ExampleParams.aantalok.ToString(), out tempvalue))
                    {
                        aantalok_previous = tempvalue.ParseAsInt(0);
    
                    }

    However, I get the answer that tempvalue is Null. (using a breakmode). I checked the break mode and it showed that it searched for "aantalok", but somehow it still returned Null from the dictionary, because VS showed that it could not find it as a key.

    So my questions are:

    1) Did I do something wrong here? If so, how do I do it right?

    2) How can I check the values in the dictionary myself?

    If you need extra info, please tell me.

    Thanks in advance, Ganesh

    Wednesday, October 11, 2017 10:18 AM

All replies

  • I am a bit confused by your examples.

    Your first code for getDefaultParams creates a dictionary of dictionaries. The first dictionary uses the DParam class as a key, with values that are dictionaries with an int key.

    And yet your example of looking in the dictionary uses a string value as a look up (ExampleParams.aantalok.ToString()). I would not expect that to even compile, so I must be missing something.

    One thing to bear in mind though is if you use a reference variable (a class such as DParams) as a key to a dictionary, then the dictionary must have some way of comparing separate instances of this class to know if they are equal or not.

    By default, two such classes will NOT be equal to each other, even if all the properties of the class are the same!

    E.g

    Dictionary<DParam, string> testDict = new Dictionary<DParam, string>();
    
    // Add value
    DParam parm = new DParam() {eenheid = "BLAH"};
    
    testDict.Add(parm, "Some value");
    
    // Look up value
    
    DParam parm2 = new DParam() {eenheid = "BLAH"};
    
    string s = testDict[parm2];  // << WILL FAIL!

    This fails because even though parm and parm2 contain a DParam with exactly the same property values, they are two separate instances of the class and, as far as the dictionary is concerned, two separate unequal things. It would only work if the exact same instance of DParam, i.e. the parm variable was used for both adding and looking up the value.

    If you want two DParams with the some or all of the same property values to be considered 'identical' then you must implement the IEqualityComparer interface, or you can pass an EqualityComparer into the dictionary constructor as per this example




    • Edited by RJP1973 Wednesday, October 11, 2017 10:53 AM
    • Proposed as answer by Fei HuModerator Tuesday, October 17, 2017 11:05 AM
    Wednesday, October 11, 2017 10:50 AM