3

I have a class named SomeClass. I have few dictionaries in it.

public class SomeClass
{
    public Dictionary<double, int[]> Dict1;
    public Dictionary<double, int[]> Dict2;
    public Dictionary<double, int[]> Dict3;
}

I get to know the dictionary name at runtime. Means In which dictionary I need to assign the data is only known at runtime. I get the dictionary name in string dynamically. Something like -

String dictName = "Dict1"; //Achieved through some code mechanism in my project.

SomeClass DynValue = new SomeClass();
DynValue.[dictName/* Known at run time */].Add(3, new int[] { 5, 10 });
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Arpit Gupta
  • 1,209
  • 1
  • 22
  • 39
  • 1
    [Dictionary](https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx) requires types for keys and values. Dictionary is invalid syntax. You probably need [List](https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx) – Shreyas Murali Mar 24 '17 at 06:44
  • Side note. you might want to rethink [using double as the datatype](http://stackoverflow.com/a/9230418/1635109) for the key – Shreyas Murali Mar 24 '17 at 07:17

3 Answers3

5

You should initialize dictionaries after object creation.

public class SomeClass
{
    public Dictionary<double, int[]> Dict1 = new Dictionary<double, int[]>();
    public Dictionary<double, int[]> Dict2 = new Dictionary<double, int[]>();
    public Dictionary<double, int[]> Dict3 = new Dictionary<double, int[]>();
}

For dynamically change the object field using name, you should use reflection:

    String dictName = "Dict1"; //Achieved through some code mechanism in my project.

    SomeClass obj = new SomeClass();

    // Get dictionary interface object of 'Dict1' field using reflection
    var targetDict = obj.GetType().GetField(dictName).GetValue(obj) as IDictionary;

    // Add key and value to dictionary
    targetDict.Add(3.5d, new int[] { 5, 10 });

If you needed to initialize dictionary using reflection, you should use this:

String dictName = "Dict1"; //Achieved through some code mechanism in my project.

SomeClass obj = new SomeClass();

// Get field info by name
var dictField = obj.GetType().GetField(dictName);

// Get dictionary interface object from field info using reflection
var targetDict = dictField.GetValue(obj) as IDictionary;
if (targetDict == null) // If field not initialized
{
    // Initialize field using default dictionary constructor
    targetDict = dictField.FieldType.GetConstructor(new Type[0]).Invoke(new object[0]) as IDictionary;

    // Set new dictionary instance to 'Dict1' field
    dictField.SetValue(obj, targetDict);
}

targetDict.Add(3.5d, new int[] { 5, 10 });
Ivan Kishchenko
  • 795
  • 4
  • 15
1

I agree reflection is nice.

When population with large number items possibly in loops, reflection might not be that performant. Only profiling will tell.

If you have small(or fixed) number of internal dictionaries, may I suggest going with something like below. I have taken the liberty of using nameof to make the below code refactoring safe.

class SomeClass
{
    private readonly Dictionary<double, int[]> Dict1 = new Dictionary<double, int[]>();
    private readonly Dictionary<double, int[]> Dict2 = new Dictionary<double, int[]>();
    private readonly Dictionary<double, int[]> Dict3 = new Dictionary<double, int[]>();

    public Dictionary<double, int[]> this[string index]
    {

        get
        {
            switch(index)
            {
            case nameof(Dict1)) return Dict1;
            case nameof(Dict2)) return Dict2;
            case nameof(Dict3)) return Dict3;
            default:
                throw new KeyNotFoundException(index);
            }            
        }
    }

    public static void Main(string[] args)
    {
        var c = new SomeClass();
        c["Dict1"].Add(42.0, new [100, 200]);
        c["Dict20"].Add(43.0, new [102, 203]); //  KeyNotFoundException("Dict20")
    }
}
Shreyas Murali
  • 426
  • 2
  • 8
  • 14
1

I would add another dictionary of dictionaries, initialized to the private dictionaries you have.

This way, you can lookup without looping, have no reflection or dynamic properties.

thst
  • 4,592
  • 1
  • 26
  • 40