为了防止文章内容太乱,所以之前的所有文章都是通过反射获取公有变量。这一篇就是只记录C#非公有成员的操作。同时这一章更加体现出反射的强大:
- 对于非公有类可以创建其对象。
- 对于非公有字段可以获取及修改其值。
- 对于非公有方法可以获取及调用。
为什么要说是非公有成员呢?因为除了public是公有,其它类型的保护修饰符都是属于private的,在第二篇文章中有讲到。
那反射公有成员和非公有成员有什么不同呢?其实原理都是一样的,在访问非公有成员时只需要加上BindingFlags
即可。BindingFlags
是一个枚举,常用的有:
BindingFlags |
解释 |
BindingFlags.Public |
公有 |
BindingFlags.NonPublic |
非公有 |
BindingFlags.Instance |
实例成员 |
BindingFlags.Static |
静态成员 |
BindingFlags.IgnoreCase |
忽略成员大小写 |
BindingFlags.CreateInstance |
调用构造函数 |
BindingFlags.InvokeMethod |
调用方法 |
前置类如下,下面通过反射获取下面成员。 |
|
可以看出只需要对公有成员的反射操作稍加修改即可实现反射非公有成员,下面例子看看吧。
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Animal { private int ID = 1001; private int Age { get; set; } private Animal() { } private Animal(int age) { Age = age; } private void Speak() { Console.WriteLine("沉默中..."); } private void Speak(string msg) { Console.WriteLine("says: " + msg); }
private static string MSG = "hello!"; private static int Exp { get; set; } private static int Calculate(int a, int b) { return a + b; } }
|
实例化私有对象
1 2 3 4 5 6 7 8
| Assembly assembly = Assembly.GetExecutingAssembly(); Type type = assembly.GetType("Study.Animal"); object obj = Activator.CreateInstance(type, true);
ConstructorInfo constructor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); object obj = constructor.Invoke(new object[] { });
|
非静态成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| FieldInfo field = type.GetField("ID", BindingFlags.NonPublic | BindingFlags.Instance); Console.WriteLine(field.GetValue(obj)); field.SetValue(obj, 999); Console.WriteLine(field.GetValue(obj));
PropertyInfo property = type.GetProperty("Age", BindingFlags.NonPublic | BindingFlags.Instance); Console.WriteLine(property.GetValue(obj)); property.SetValue(obj, 99); Console.WriteLine(property.GetValue(obj));
MethodInfo method = type.GetMethod("Speak", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null); method.Invoke(obj, new object[] { "hello" });
|
静态成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| FieldInfo field = type.GetField("MSG", BindingFlags.NonPublic | BindingFlags.Static); Console.WriteLine(field.GetValue(null)); field.SetValue(null, "hi"); Console.WriteLine(field.GetValue(null));
PropertyInfo property = type.GetProperty("Exp", BindingFlags.NonPublic | BindingFlags.Static); Console.WriteLine(property.GetValue(null)); property.SetValue(null, 999); Console.WriteLine(property.GetValue(null));
MethodInfo method = type.GetMethod("Calculate", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(int), typeof(int) }, null); object result = method.Invoke(null, new object[] { 100, 100 }); Console.WriteLine(result);
|