C# 反射

如果需要更详细理解可查看:https://www.cnblogs.com/loveleaf/p/9923970.html,我也是看这里做的笔记

设置相关程序集:
using System;

namespace ClassLibrary1
{
    public class Class1
    {
        #region 设置相关反射集
        public Class1()
        {
            //
        }
        public Class1(string Name)
        {
            this.Name = Name;
        }
        public string Name { get; set; }
        public int Age { get; set; }
        public bool Sex { get; set; }
        public void Eat()
        {
            Console.WriteLine("我要公开吃...");
        }
        protected void ProEat()
        {
            Console.WriteLine("我要保护吃...");
        }
        private void PriEat()
        {
            Console.WriteLine("我要偷偷吃...");
        }
        public string ReturnEat()
        {
            return "给你吃";
        }
        public void NameEat(string Name)
        {
            Console.WriteLine(string.Format("{0}要来抢吃的...",Name));
        }
        #endregion
    }
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;  // 反射集Assembly相关引入
using System.Diagnostics;  // Stopwatch

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            #region
            // 获取程序集信息
            Assembly assembly = Assembly.LoadFile(@"E:C#CodeClassLibrary1ClassLibrary1inDebugClassLibrary1.dll");  // 根据反射集的地址进行引用。使用LoadFile()需要使用绝对路径;Load()获取的方式有很多,可以通过流的方式获取,但使用的最多的还是相对路径
            Console.WriteLine(string.Format("程序集的名字:{0}", assembly.FullName));  // 输出调用程序集名字和版本信息
            Console.WriteLine(string.Format("程序集的位置:{0}", assembly.Location));  // 输出调用程序集绝对路径
            Console.WriteLine(string.Format("运行程序集需要的CLR版本:{0}", assembly.ImageRuntimeVersion));
            Console.WriteLine("===============================================================================================");

            // 获取模块信息
            Module[] modules = assembly.GetModules();  // 获取程序集所有的模块
            foreach(Module item in modules)
            {
                Console.WriteLine(string.Format("模块的名称:{0}", item.Name));  // 即程序集的全称,包括后缀
                Console.WriteLine(string.Format("模块的版本ID:{0}", item.ModuleVersionId));
            }
            Console.WriteLine("===============================================================================================");

            // 获取类
            Type[] types = assembly.GetTypes();
            foreach(Type item in types)
            {
                Console.WriteLine(string.Format("类型的名称:{0}", item.Name));
                Console.WriteLine(string.Format("类型的完全名称:{0}", item.FullName));
                Console.WriteLine(string.Format("类型的类别:{0}", item.Attributes));
                Console.WriteLine(string.Format("类型的GUID:{0}", item.GUID));
                Console.WriteLine("===============================================================================================");
            }

            // 获取类的成员
            Type ClassType = assembly.GetType("ClassLibrary1.Class1");  // 获取指定类的属性/方法等。对应的空间名和class获取对应的类型
            MemberInfo[] mi = ClassType.GetMembers();  // 仅能够获取公共成员属性和方法
            foreach (MemberInfo item1 in mi)
            {
                Console.WriteLine(string.Format("成员的名称:{0}", item1.Name));
                Console.WriteLine(string.Format("成员类别:{0}", item1.MemberType));
            }
            Console.WriteLine("===============================================================================================");

            // 获取方法(BindingFlags用来加以控制获取成员的类型)
            BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance;  // 规定查找规则:public类型,自己定义的方法(不包括继承的),实例成员。其中还有GetField(获取字段值,对SetField无效)、GetField(构造函数)
            MethodInfo[] methodInfo = ClassType.GetMethods(flags);  // 指定查找规则
            foreach (MethodInfo item1 in methodInfo)
            {
                Console.WriteLine("Public类型的,不包括基类继承的实例方法:{0}", item1.Name);
            }
            Console.WriteLine("===============================================================================================");
            BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic;  // NonPublic为非公共的方法规则
            MethodInfo[] methods = ClassType.GetMethods(flag);
            foreach(MethodInfo item1 in methods)
            {
                Console.WriteLine(string.Format("非Public类型的,不包括基类继承的实例方法:{0}", item1.Name));
            }
            Console.WriteLine("===============================================================================================");

            // 获取属性
            BindingFlags flag2 = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance;
            PropertyInfo[] pi = ClassType.GetProperties(flag2);
            foreach(PropertyInfo item1 in pi)
            {
                Console.WriteLine(string.Format("属性的名称:{0}", item1.Name));
            }
            #endregion

            #region 反射应用的实例一:Activator.CreateInstance
            // 调用无参构造函数(注:使用Activaotr.CreateInstance时如果定义了有参构造函数无须再定义无参构造,不会报错)
            // ClassType 同上
            object obj = Activator.CreateInstance(ClassType);
            if (obj!=null)
            {
                Console.WriteLine("无参:" + obj.GetType());
            }
            Console.WriteLine();
            
            // 调用有参构造函数
            obj = Activator.CreateInstance(ClassType, new object[] { "namejr" });
            if(obj!=null)
            {
                Console.WriteLine("有参:" + obj.GetType());
            }
            #endregion

            #region 反射应用的实例一:Assembly.CreateInstance
            // assembly/ClassType 同上
            // 无参(注:使用Assembly.CreateInstance时如果定义了有参构造函数必须再定义无参构造(无参构造函数必须存在,否则有参回覆盖),不然会报错)
            object o = assembly.CreateInstance(ClassType.FullName, true);
            Console.WriteLine(o.GetType());
            
            // 有参
            // 调用类中的其它方法(Activator同例),调用方法有两种:InvokeMember、Invoke、Stopwatch

            // 使用type类中的InvokeMember方法:
            Type instanceType = o.GetType();
            // instanceType.InvokeMember("Eat", BindingFlags.SetProperty,null,o,null)
            // 第一个参数为String类型,为指定构造函数、方法名、字段、属性
            // 第二个参数为指定规则,SetProperty(设置值)、GetProperty(获取值)、InvokeMethod(调用函数)
            // 第三个参数(不是很理解解释,不做解释)
            // 第四个参数指定成员的对象
            // 第五个参数传递的参数
            instanceType.InvokeMember("Name", BindingFlags.SetProperty, null, o, new object[] { "namejr" });  // 设置Name
            string Name = instanceType.InvokeMember("Name", BindingFlags.GetProperty, null, o,null).ToString();  // 获取设置的Name
            Console.WriteLine(string.Format("获取到设置的name为:{0}",Name));
            instanceType.InvokeMember("Eat", BindingFlags.InvokeMethod, null, o, null);  // 调用Eat函数(无参)
            instanceType.InvokeMember("NameEat", BindingFlags.InvokeMethod, null, o, new object[] { "namejr"});  // 调用Eat函数(有参参)

            // 使用FieldInfo/MethodInfo等中的Invoke
            // FieldInfo
            PropertyInfo ps = instanceType.GetProperty("Age", typeof(Int32));  // 获取对应字段
            ps.SetValue(o, 5, null);  // 设置值
            PropertyInfo pi2 = instanceType.GetProperty("Age");  // 获取对应字段
            Console.WriteLine(pi2.GetValue(o, null));  // 获取值
            // MethodInfo
            MethodInfo mi1 = instanceType.GetMethod("NameEat", BindingFlags.Instance | BindingFlags.Public);  // 设置函数
            object obj1 = mi1.Invoke(o, new object[] { "Namejr" });  // 调用函数

            // 反射优化,Stopwatch
            Stopwatch sw = new Stopwatch();
            sw.Start();
            
            // 属性
            PropertyInfo ps1 = instanceType.GetProperty("Age", typeof(int));
            ps1.SetValue(o, 5, null);
            PropertyInfo pi3 = instanceType.GetProperty("Age");
            Console.WriteLine(pi3.GetValue(o, null));
            Console.WriteLine(string.Format("属性没启用优化所需时间:{0}", sw.Elapsed));
            // 优化属性(使用委托)
            sw.Reset();
            sw.Restart();
            PropertyInfo pi4 = instanceType.GetProperty("Age", typeof(int));
            Action<int> piDele = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), o, pi4.GetSetMethod());
            piDele(5);
            Func<int> Result1 = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), o, pi4.GetGetMethod());
            Console.WriteLine(string.Format("获取设置的Age:{0}", Result1()));
            Console.WriteLine(string.Format("属性启用优化所用时间:{0}", sw.Elapsed));

            // 方法
            sw.Reset();
            sw.Restart();
            MethodInfo mi2 = instanceType.GetMethod("NameEat", BindingFlags.Instance | BindingFlags.Public);
            object obj2 = mi2.Invoke(o, new object[] { "Namejr" });
            Console.WriteLine(string.Format("方法没启用优化所需时间:{0}", sw.Elapsed));
            // 优化方法(委托)
            sw.Reset();
            sw.Restart();
            MethodInfo mi3 = instanceType.GetMethod("ReturnEat", BindingFlags.Instance | BindingFlags.Public);
            Func<string> miDele = (Func<string>)Delegate.CreateDelegate(typeof(Func<string>),o,mi3);
            Console.WriteLine("方法启用优化所需时间:{0}", sw.Elapsed);
             #endregion
            Console.ReadKey();
        }
    }
}
原文地址:https://www.cnblogs.com/namejr/p/11220558.html