我如何在反射 class 期间访问 List<int> 值?

How do I access List<int> value during reflection of a class?

我对 Reflection 还很陌生,但已经能够检索我传递的 class 的所有字段。现在我正在尝试检索每个字段的值,但我遇到了 List<T>.

的问题

我有一个简单的class用于测试:

    public class MyTestClass
    {
        public string Name;
        public int Age;
        public bool Alive;
        public List<int> Counters;
        public List<string> People;
        public List<Tool> Tools;
        public string[] Stuff;
        public Tool[] NeededTools;

        public MyTestClass(string name, int age, bool alive = true)
        {
            Name = name;
            Age = age;
            Alive = alive;
            Counters = new List<int>();
            Counters.Add(7);
            People = new List<string>();
            People.Add("Seven");
            Tools = new List<Tool>();
            Stuff = new string[2];
            NeededTools = new Tool[3];
        }
    }

这是我使用的代码:

    private void AttachControl(object source, FieldInfo fi, Control control)
    {
        switch (fi.FieldType.Name)
        {
            case "Boolean":
                (control.Controls[fi.Name] as ComboBox).SelectedIndex = (fi.GetValue(source).ToString().ToUpper() == "TRUE") ? 1 : 0;
                break;
            case "List`1":
                Control listControl = control.Controls[fi.Name];
                var listType = fi.FieldType.GetGenericArguments();

                var listFields = listType[0].GetFields(
                                       BindingFlags.Public |
                                       BindingFlags.Instance
                                       );
                if (listFields.Length > 0)
                {
                    AttachToControls(listFields, listControl.Controls.Cast<Control>().ToArray());
                }
                else
                {
                    // *** Here is the issue ***
                    var values = fi.GetValue(source);
                    listControl.Controls[fi.Name].Text = values[0].ToString();
                }
                break;
            default:
                control.Controls[fi.Name].Text = fi.GetValue(source).ToString();
                break;
        }
    }

当我到达 Counters 时,我可以检索值 var values = fi.GetValue(source); 并且在调试期间我可以看到其中包含值 7 的列表,但是它指出

cannot apply indexing with [] to an expression of type object on the line: listControl.Controls[fi.Name].Text = values[0].ToString();

我想我需要转换它,但它不会总是一个 int 类型。我需要为每种类型写一个部分还是有更简单的方法来完成我需要的?

仅供参考 - 我正在编写一个 Class 库,它将允许我传递任何 class 并自动创建一个表单来编辑所有字段。

我的建议是:

var bob = values as IEnumerable;
listControl.Controls[fi.Name].Text = bob?.Cast<object>()?.FirstOrDefault()?.ToString();

因为你想要的是 string(不是特定类型),所以上面的代码可以正常工作(假设值是某种形式的可枚举,如列表或数组)。

请特别注意,IEnumerable 接口是 this one, not the more commonly used IEnumerable<T>。这允许您在没有特定类型的情况下使用它。