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

C# 从类中动态访问字典,而不知道其名称,c#,dictionary,C#,Dictionary,我有一个名为SomeClass的类。我有几本字典在里面 public class SomeClass { public Dictionary<double, int[]> Dict1; public Dictionary<double, int[]> Dict2; public Dictionary<double, int[]> Dict3; } 您应该在对象创建之后初始化字典 public class SomeClass {

我有一个名为
SomeClass
的类。我有几本字典在里面

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

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

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

如果需要使用反射初始化字典,则应使用以下方法:

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

我同意反射很好

当循环中可能包含大量项时,反射可能不会有那么好的性能。只有分析才能说明问题

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

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")
    }
}
class-SomeClass
{
专用只读词典Dict1=新词典();
专用只读词典Dict2=新词典();
专用只读词典Dict3=新词典();
公共字典[字符串索引]
{
得到
{
开关(索引)
{
(Dict1)的案例名称返回Dict1;
(Dict2)返回Dict2的案例名称;
(Dict3)的案例名称返回Dict3;
违约:
抛出新的KeyNotFoundException(索引);
}            
}
}
公共静态void Main(字符串[]args)
{
var c=新的SomeClass();
c[“Dict1”]添加(42.0,新增[100200]);
c[“Dict20”].Add(43.0,new[102203]);//KeyNotFoundException(“Dict20”)
}
}

我将添加另一个字典字典,初始化为您拥有的私有字典


通过这种方式,您可以在不循环的情况下进行查找,并且没有反射或动态属性。

需要键和值的类型。字典的语法无效。你可能需要补充说明。您可能想重新考虑一下这个键,您也可以使用反射动态初始化字段。@Andrey Alonzov,是的,您是对的。增加了一个例子。
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 });
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")
    }
}