什么是反射?
很多时候被问到什么是反射时,都说不出一个准确的定义。那什么是反射呢,其实我们在使用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:\Users\Administrator\Desktop\plm_20181031\plm\ConsoleApplication1\testDll\bin\Debug\testDll.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(); } } }