演示类
示例类具有一个私有实例字段,一个实例属性,一个实例字段,一个静态私有属性。
class Fight
{private int hp;public int Hp{get => hp; set{if (value > 0){ hp += value; }else if (-value > Def){ hp += value - Def; }}}public int Atk;private static int Def { get; set; }
}
获取字段的值
由于获取的字段是实例字段,因此需要传入一个实例来获取。但如果是静态成员,这个参数可以是null。
Type type = typeof(Fight);
FieldInfo field = type.GetField("hp", BindingFlags.NonPublic | BindingFlags.Instance);Fight fight = new Fight();
object hp = field.GetValue(fight);
Console.WriteLine(hp);
获取到的值确实就是那个类当前情况的值。
在那个类变化后,再次获取到他的值,能获取到变化后的值。
反射相关的api用的参数和返回值类型都是object,但他就是声明类型的值,可以强转。
fight.Hp = 60;
int hp2= (int)field.GetValue(fight);
Console.WriteLine(hp);
设置字段的值
设置字段的值使用setValue方法。通用你需要传入有这个字段的实例。
第一个参数是实例,第二个参数是你用来赋值的值。
他的参数只要求是object,但你要保证他是可以赋值的。
(类型匹配,且字段不是只读。但如果是你程序集的东西,可以无视访问修饰符)
field.SetValue(field, 999);
Console.WriteLine(fight.Hp);
获取和设置属性的值
和上述差不多。但属性需要保证访问器是正确的。
例如存在get/set访问器,类型正确,且不是抽象的(抽象类中的属性可以是抽象的,这种访问器没有实现)。
PropertyInfo property = type.GetProperty("Def", BindingFlags.Static | BindingFlags.NonPublic);
int i2 = (int)property.GetValue(null);
Console.WriteLine(i2);property.SetValue(null,999);
Console.WriteLine(property.GetValue(null));