C#之反射
来源:互联网 发布:微信多开软件苹果版 编辑:程序博客网 时间:2024/05/16 06:19
最近在看反射就把获取各种常用类型变量的方法总结了一遍。C#编译时会把类的信息,变量,特性等都注册在一张表上,而基于System.Reflection下的Assembly,Type类等都可以获取这个表的内容。从而达到根据字符串获取一个类的实例,方法,变量,委托,事件等,以上行为即是我理解的C#的反射过程。代码如下:
一个随意定义的待测试类和通过反射获取各种类型变量的逻辑。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Reflection;namespace sgs{ class Class1 { private int num1 = 10; //私有变量 public int num2 = 20; //公有变量 public static int num3 = 30; //公有静态变量 private Class2 c2; //私有实例变量 public delegate int Fool(string para); public event Fool FoolEvent; public Class1() { c2 = new Class2(); } public int Num1 { get { return num1; } set { this.num1 = value; } } private void PrivatePrint() { Console.WriteLine("private print: {0}", num1); EventInfo e; } public int PublicPrint() { Console.WriteLine("public print: {0}", num2); return num1; } public int FoolMethod(string str) { return 100; } } class Class2 { }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Reflection;using System.Threading;using sgs;namespace ConsoleApplication4{ class Program { static void Main(string[] args) { object result = InvokePublicMethod("sgs.Class1", "PublicPrint", null); Console.WriteLine("reflect public method result : {0}", result.ToString()); object propertyResult = GetProperty("sgs.Class1", "Num1"); Console.WriteLine("reflect property result : {0}", propertyResult.ToString()); object variableResult = GetPublicVariable("sgs.Class1", "num3"); Console.WriteLine("reflect public or static variable : {0}", variableResult); variableResult = GetPrivateVariable("sgs.Class1", "c2"); Console.WriteLine("reflect private or instance variable : {0}", variableResult); object class1 = GetClassInstance("sgs.Class1"); Console.WriteLine("reflect class instance : {0}", class1); object delegateResult = GetDelegate("sgs.Class1", "Fool", "FoolMethod", "sgs"); Console.WriteLine("reflect delete result : {0}", delegateResult); object eventResult = GetEvent("sgs.Class1", "FoolEvent", "sgs"); } // 获取公有方法 private static object InvokePublicMethod(string classFullName, string methodName, params object[] paras) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); MethodInfo methodInfo = type.GetMethod(methodName); return methodInfo.Invoke(obj, paras); } // 获取字段属性 private static object GetProperty(string classFullName, string propertyName) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); PropertyInfo propertyInfo = type.GetProperty(propertyName); return propertyInfo.GetValue(obj); } // 获取公有变量或静态变量 private static object GetPublicVariable(string classFullName, string variableName) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); FieldInfo variableInfo = type.GetField(variableName, BindingFlags.Public | BindingFlags.Static); return variableInfo.GetValue(obj); } // 获取私有变量或实例变量 private static object GetPrivateVariable(string classFullName, string variableName) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); FieldInfo variableInfo = type.GetField(variableName, BindingFlags.Instance | BindingFlags.NonPublic); return variableInfo.GetValue(obj); } // 获取类实例 private static object GetClassInstance(string classFullName) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); return obj; } //获取委托,委托类型在编译后作为类的嵌套类型,所以调用GetNestedType方法 private static object GetDelegate(string classFullName, string delegateName, string methodName, params object[] paras) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); Type delegateInfo = type.GetNestedType(delegateName); MethodInfo methodInfo = type.GetMethod(methodName); //注意调用CreateDelegate方法时若方法是实例方法则需调用CreateDelegate重载的带实例对象参数的方法! Delegate delegateInstance = Delegate.CreateDelegate(delegateInfo, obj, methodInfo); return delegateInstance.DynamicInvoke(paras); } //获取事件,注意获取事件需要设置绑定参数为实例和非public,此处我也不清楚事件为什么作为非公有参数。。。 private static object GetEvent(string classFullName, string eventName, params object[] paras) { Type type = Type.GetType(classFullName); object obj = Activator.CreateInstance(type); EventInfo eventInfo = type.GetEvent(eventName); eventInfo.AddEventHandler(obj, new Class1.Fool((string str) => { return 400; })); eventInfo.AddEventHandler(obj, new Class1.Fool((string str) => { return 800; })); MulticastDelegate multicasDelegate = (MulticastDelegate)type.GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); foreach (Delegate dele in multicasDelegate.GetInvocationList()) { Console.WriteLine(dele.Method.Name); object c = dele.DynamicInvoke(paras); Console.WriteLine("{0}", c); } Console.WriteLine(eventInfo.RaiseMethod); return multicasDelegate; } } }
在获取事件的时候对于变量获取绑定标志的设定是BindingFlags.Instance | BindingFlags.NonPublic,这里我也不清
楚为什么事件是非公有的,但如果设定为公有是获取不到事件的,其次关于委托的delegate关键字,其实是为了在编译
时自动生成一个继承于MulticastDelegate的委托类,所以所有委托都是从这个类继承下来的,再往上则是我们熟悉的
Delegate类,在解析件时,我们应该获取到需要的类实例,将其通过MulticastDelegate分解为委托链,通过
DynamicInvoke调用各委托绑定的方法即可。0 0
- C#之反射
- C#反射之Assembly
- c#之反射_FieldInfo_GetField_
- C#之反射
- C#之反射
- C#之反射
- C#反射之初始
- c#之反射
- JAVA反射与C#反射之比较
- JAVA反射与C#反射之比较
- C#高级编程之“反射”
- C#高级编程之“反射”
- C#反射之基础应用
- C#反射之基础应用
- C#基础之反射(Reflection)
- C#之玩转反射
- C#之玩转反射
- C#之玩转反射
- Android 热修复 Tinker 源码分析之DexDiff / DexPatch
- docker版本对应
- HttpServletResponse
- elasticsearch服务器开发学习笔记(三.二)
- Weblogic反序列化漏洞补丁更新解决方案
- C#之反射
- QEMU
- 一个例子理清楚遗传算法
- Android面试题大全
- javascript 的 && 和 ||
- Java知识点总结
- 自定义Drawable,点击效果出不来的问题
- 如何查看OSB默认数据库(Derby)的表数据
- 查找算法