我有一个结构,有很多名为bool的成员。 (为了这个例子,请留下好的做法,现在不考虑这些。)
我想将这些值随机设置为true或false,仅用于测试目的。
我如何通过反思来做到这一点?
这是我到目前为止所做的:
Random r = new Random();
foreach (var bool_field in state.GetType().GetFields().Where(x => x.GetType() == false.GetType()))
{
bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false);
}
不幸的是,它永远不会进入循环。
更新1:
以下是SystemState结构的外观,它是 state 变量的类型。它充满了布尔汽车的特性。
public struct SystemState
{
...
public bool CanYouHelpMeOnThisOne { get; set; }
...
}
更新2:
下面发布的解决方案似乎很好,但它不起作用。原因是SystemState是一个结构而不是一个类。因此,它是Value类型而不是Reference类型,因此调用SetValue方法无效。将SystemState更改为class后,以下解决方案可以正常运行。
现在有没有其他方法可以在不将SystemState更改为类的情况下实现此目的?
答案 0 :(得分:10)
首先,您需要更改Where
子句:
x => x.FieldType == false.GetType()
x
的类型为FieldInfo
自上次OP编辑以来,它不是字段,而是属性。因此,您应该使用GetProperties
获取属性列表,然后比较PropertyType
,因为x
将是PropertyInfo
。此外,SetValue
方法还有其他签名。
foreach (var bool_field in state.GetType()
.GetProperties()
.Where(x => x.PropertyType == false.GetType()))
{
bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false, null);
}
根据OP的评论,如果您确实想要访问支持字段,可以使用以下代码:
var fs = state.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.FieldType == typeof(bool));
foreach (var f in fs)
{
f.SetValue(state, true);
}
不带参数的GetFields
的重载会返回当前Type的所有公共字段。在您的情况下,您需要private
个,因此请使用Type.GetFields Method (BindingFlags)和BindingFlags
。{/ p>