我如何在反射 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>
。这允许您在没有特定类型的情况下使用它。
我对 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>
。这允许您在没有特定类型的情况下使用它。