什么是反射?
很多时候被问到什么是反射时,都说不出一个准确的定义。那什么是反射呢,其实我们在使用vs编译器的智能提示,就是通过反射获取到类的属性、方法等。
还有反编译工具也是通过反射实现
反射就是动态获取程序集的元数据的功能。
反射:就是动态获取程序集中的元数据来操作类型的。(简单的理解就是通过类型元数据创建对象、调用对象成员等)
Type类的介绍
Type类是反射的一个重要的类,通过它我们可以获取类中的所有信息包括方法、属性等,可以动态调用类的属性、方法。
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { //对Type的介绍 //1.获取一个类型的Type(该类型的类型元数据) MyClass m = new MyClass(); Type type1 = m.GetType();//获得了类型MyClass对应的Type. //没有创建MyClass对象,通过typeof关键字 Type type2 = typeof(MyClass); //获取该当前类型的父类 Console.WriteLine(type2.BaseType.ToString()); //Console.WriteLine(type2.BaseType.BaseType.ToString()); // Console.WriteLine(type2.BaseType.BaseType.BaseType.ToString()); // //字段信息(public) FieldInfo[] a = type2.GetFields(); for (int i = 0; i < a.Length; i++) { Console.WriteLine(a[i].Name); } //属性获取 PropertyInfo[] pro = type2.GetProperties(); for (int i = 0; i < pro.Length; i++) { Console.WriteLine(pro[i].Name); } //获取方法 MethodInfo [] method = type2.GetMethods(); for (int i = 0; i < method.Length; i++) { Console.WriteLine(method[i].Name); } Console.ReadKey(); } } class MyClass { public string[] member; public string[] student; public string name { get; set; } public string Email { get; set; } public int age { get; set; } public void Say() { Console.WriteLine("早安,你好"); } private void SayHello() { Console.Write("你在哪里啊"); } } }
动态加载程序集
创建一个testDll类库找到编译生成的dll
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace testDll { public class Person { public Person() { } public Person(string name , int age, string sex) { this.name = name; this.age = age; this.sex= sex; } public string name { get; set; } public int age { get; set; } public string sex { get; set; } public void SayHi() { Console.WriteLine("Hi~~~~"); } public void SayHello(string msg) { Console.WriteLine(msg); } public void SayHello() { Console.WriteLine("hi,我是SayHello的无参重载方法。"); } public int Add(int n1, int n2) { return n1 +n2; } } public interface IFlyable { void Fly(); } public class Student : Person{ } internal class Teacher : Person { } public class MyClass1 : IFlyable { #region IFlyable 成员 public void Fly() { throw new NotImplementedException(); } #endregion } public delegate void a(); public struct Mystruct { } public enum MyEnum { } }
根据程序的路径,动态加载一个程序集
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //动态加载程序集并且调用类型成员 //根据程序的路径,动态加载一个程序集 Assembly myAssembly = Assembly.LoadFile(@"C:UsersAdministratorDesktopplm_20181031plmConsoleApplication1 estDllinDebug estDll.dll"); //// 1.获取程序集中的所有类型 // Type[] type1 = myAssembly.GetTypes(); // for (int i = 0; i < type1.Length; i++) // { // Console.WriteLine(type1[i].FullName); // } //2.获取所有的public的类型 //Type[] type = myAssembly.GetExportedTypes(); //for (int i = 0; i <type.Length; i++) //{ // Console.WriteLine(type[i].FullName); //} //获取指定类型 //获取person类型的type Type typePerson = myAssembly.GetType("testDll.Person"); //调用Person类中的方法 //调用SayHi方法 // MethodInfo method = typePerson.GetMethod("SayHi"); ////创建一个Person 类型的对象 // object obj = Activator.CreateInstance(typePerson); // //调用方法 // method.Invoke(obj, null); //MethodInfo method = typePerson.GetMethod("SayHello", new Type[] { typeof(string) }); //method.Invoke(Activator.CreateInstance(typePerson), new object[] { "大家好。。。。" }); //如果有返回值,就直接接受invoke的返回值 //通过调用指定的构造函数来创建对象 ConstructorInfo info = typePerson.GetConstructor(new Type []{typeof(string ),typeof(int ), typeof(string )}); //调用构造函数来创建对象 object obj = info.Invoke(new object[]{"张正",20,"男"}); //通过反射获取指定对象的属性值 PropertyInfo pinfo = typePerson.GetProperty("name"); string name = pinfo.GetValue(obj, null).ToString(); Console.WriteLine(name); Console.ReadKey(); } } }