C# 简单易懂之反射

倾然丶 夕夏残阳落幕 提交于 2020-01-01 12:02:05

------------恢复内容开始------------

我学习反射的时候,看了好多文章,各种前辈的理解,让我少走了很多弯路,致此,我想写一份对新手通俗易懂的 关于反射的文章,有什么不对的地方希望指正

反射其实并没有多难,只要想通,其实不难 (注:代码在最后)

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------------

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!