从类中动态访问字典而不知道其名称

时间:2017-03-24 06:35:02

标签: c# dictionary

我有一个名为SomeClass的班级。我的词典很少。

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

我在运行时了解字典名称。手段我需要在哪个字典中分配数据只在运行时知道。 我动态地在string中获得字典名称。像 -

这样的东西
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 });

3 个答案:

答案 0 :(得分:5)

您应该在创建对象后初始化字典。

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[]>();
}

要使用name动态更改对象字段,您应该使用反射:

    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 });

如果您需要使用反射初始化字典,则应使用:

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 });

答案 1 :(得分:1)

我同意反思很好。

当具有大量项目的人口可能处于循环中时,反射可能不是那么高效。只有剖析才能说明。

如果您有少量(或固定)内部词典,我建议您使用下面的内容。我冒昧地使用nameof来使下面的代码重构安全。

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")
    }
}

答案 2 :(得分:1)

我会添加另一个字典词典,初始化为您拥有的私人词典。

这样,您可以在不循环的情况下进行查找,没有反射或动态属性。