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
原创粉丝点击