------------恢复内容开始------------
我学习反射的时候,看了好多文章,各种前辈的理解,让我少走了很多弯路,致此,我想写一份对新手通俗易懂的 关于反射的文章,有什么不对的地方希望指正
反射其实并没有多难,只要想通,其实不难 (注:代码在最后)
1.程序集(Assembly)
using System.Reflection; //程序集的命名空间
程序集包含了两种文件:可执行文件(.exe文件)和 类库文件(.dll文件),相关程序集资料可自行百度
通过 创建类库→新建类→在右击类库→点击生成→在类库的bin→debug→可以找到dll文件,dll文件也是cs生成的
程序集对反射有什么作用?
程序集是反射的起始,需要详细理解程序集由什么组成,在哪里用?本文对新手入门讲解,不包含进一步的讲解
Assembly 有三个常用的方法
(1) Assembly.Load("程序集文件名") 也就是 bll文件的名字 注:不要加 .dll
(2) Assembly.LoadFrom("程序集实际路径") 也就是这个bll文件在 那个目录下,如:@"C:\Users\Administrator\source\repos\反射学习\Common\bin\Debug\Common.dll"
(3) Assembly.LoadFrom("结对路径")载指定路径上的程序集文件的内容需要绝对路径 如:@"C:\Users\Administrator\source\repos\反射学习\Common\bin\Debug\Common.dll";
//1.按照程序集名称来找到这个程序集 Assembly Load = Assembly.Load("Test11"); //2.按照程序集的实际路径 Assembly LoadFrome = Assembly.LoadFrom(@"C:\Users\Administrator\source\repos\反射学习\反射学习\bin\Debug\Test11.dll");//3.绝对路径 Assembly LoadFile = Assembly.LoadFile(@"C:\Users\Administrator\source\repos\反射学习\Test11\bin\Debug\Test11.dll");
//注: 以上是已经动态加载好程序集,三种方法 都可以用
2.Type类
Type类是 使用反射得到类型信息的最核心的类,BCL声明了一个叫做Type的抽象类,它被设计用来包含类型的特性,使用这个类的对象能让我们获取程序使用的类型的信息
获取Tyoe对象 我知道的有两种方法
(1) 当没有对象的时候使用这种方式
Type TestType= typeof(Student);
Console.WriteLine("TypeOf的数据类型全称是:" + TypeOf);
(2) 已知对象的时候使用
Student stu = new Student();
Type TypeType = stu.GetType();
Console.WriteLine("TypeType的数据类型全称是:" + TypeType);
(3) Type的属性
Name 数据类型名
FullName 数据类型的完全限定名(包括命名空间名)
Namespace 定义数据类型的命名空间名
IsAbstract 指示该类型是否是抽象类型
IsArray 指示该类型是否是数组
IsClass 指示该类型是否是类
IsEnum 指示该类型是否是枚举
IsInterface 指示该类型是否是接口
IsPublic 指示该类型是否是公有的
IsSealed 指示该类型是否是密封类
IsValueType 指示该类型是否是值类型
(4) Type的方法
GetConstructor(), GetConstructors():返回ConstructorInfo类型,用于取得该类的构造函数的信息
GetEvent(), GetEvents():返回EventInfo类型,用于取得该类的事件的信息
GetField(), GetFields():返回FieldInfo类型,用于取得该类的字段(成员变量)的信息
GetInterface(), GetInterfaces():返回InterfaceInfo类型,用于取得该类实现的接口的信息
GetMember(), GetMembers():返回MemberInfo类型,用于取得该类的所有成员的信息
GetMethod(), GetMethods():返回MethodInfo类型,用于取得该类的方法的信息
GetProperty(), GetProperties():返回PropertyInfo类型,用于取得该类的属性的信息
可以调用这些成员,其方式是调用Type的InvokeMember()方法,或者调用MethodInfo, PropertyInfo和其他类的Invoke()方法。
(5) 使用Type属性和方法 写一个示例,其他自己试试 //和上面 (2)(3)(4) 调用 其他的 属性方法 自己试一试 都一样
MethodInfo[] methods = TypeType.GetMethods(); //获取该类的方法的信息
foreach (var item in methods)
{
Console.WriteLine( "属性名称:" + item.Name);
}
(6) 调用无参数 无返回值的方法
MethodInfo method = TypeType.GetMethod("Test1");//调用无参数无返回值方法
Console.WriteLine(method.Name);//这是拿过来方法名
object obj = Activator.CreateInstance(TypeType);//这是new 一个对象
method.Invoke(obj, null);//这是调用
Assembly Load = Assembly.LoadFrom(@"C:\Users\Administrator\source\repos\反射学习\反射学习\bin\Debug\Test11.dll"); 动态
Type type = Load.GetTypes()[0];
object obj = Load.CreateInstance(type.FullName);
MethodInfo method = type.GetMethod("Test1");
method.Invoke(obj, null);
(7) 调用带参带返回值
Assembly Load = Assembly.LoadFrom(@"C:\Users\Administrator\source\repos\反射学习\反射学习\bin\Debug\Test11.dll");
Type type = Load.GetTypes()[0];
Console.WriteLine(type);
object obj = Load.CreateInstance(type.ToString());
MethodInfo method = type.GetMethod("Test2");
object result = method.Invoke(obj, new object[] { 1,2});
Console.WriteLine($"返回值{result}");
(8) 调用带参 带返回值重载方法
重载和上面一样 区分一下 就好
更改他的 MethodInfo method = type.GetMethod("Test2",new Type[] { typeof(int),typeof(int)});
(9) 构造函数与调用方法
Assembly Load = Assembly.LoadFrom(@"C:\Users\Administrator\source\repos\反射学习\反射学习\bin\Debug\Test11.dll");
Type type = Load.GetTypes()[0]; //获取命名空间 加类名
Console.WriteLine(type);
object obj = Load.CreateInstance(type.ToString());
PropertyInfo property = type.GetProperty("Name");
property.SetValue(obj, "张三", null);//为属性赋值
string name = property.GetValue(obj, null).ToString();//获取属性值
Console.WriteLine(name);
MethodInfo method = type.GetMethod("Test");//调用方法
object result = method.Invoke(obj, null);
namespace 反射学习 {
//这是 使用的类 public class Student { public Student() { } public Student(string Name,int Age) { this.Name = Name; this.Age = Age; } public string Name { get; set; } public int Age { get; set; } public void Test() { Console.WriteLine("学生姓名:"+this.Name+"学生年龄:"+this.Age); } public void Test1() { Console.WriteLine("无参方法调用"); } public int Test2(int a,int b) { return a+b; } public int Test2(int a,int b,int c) { return a + b + c; } private void Test3() { Console.WriteLine("私有方法"); } } }
适用于新入门学习反射的,下面是qq群 可以一起互相学习 互相探讨
------------QQ群:330800272------------