• C#学习-程序集和反射


    准备项目
    1.新建一个空的解决方案MyProj.sln
    2.在该解决方案下,建一个控制台项目P01.csproj
    3.在该项目下,自己新建一个类MyFirstClass.cs
    image
    查看解决方案MyProj.sln,知道本次要编译哪个项目
    image
    查看项目文件P01.csproj(其实就是一个xml文档),可以知道本次程序会编译的类
    image
    类库编译成程序集
    在bin目录下生成*.dll或*。exe
    程序集包含哪些内容:
    类型元数据【以二进制的形式,描述代码中定义的每一个类型和成员】
    程序集元数据【程序集清单,版本号,名称等】
    IL代码【这些都被装在exe或dll中】
    资源文件【比如图片这些】
    说明:程序集是在硬盘上的,如果每次要用到某个类的话,都去硬盘上读,速度会很慢,
    所以VS会在程序第一次运行的时候,将程序集加载到内存中运行。
    程序集(*.dll,*exe) -->加载到 内存中 就是Assembly对象
    类(接口)--> 加载到内存中就是 Assembly下的Type对象
    类的成员 --> 加载到内存 就是 Type下的相应对象(FieldInfo,PropertyInfo,MethodInfo,EventInfo)
     
    什么是反射:
    1.在程序运行时,
                 动态 获取 加载程序集
                 动态 获取 类型(类,接口)
                 动态 获取 类型的成员 信息(字段,属性,方法)
    2.在运行时,
                 动态 创建类型实例,以及 调用 和访问 这些 实例 成员
    程序集(Assembly对象)===》类,接口(Type对象)===》类的成员(**Info)
     
    获取Assembly的方式:
    获取当前 应用程序域中 所有的Assembly:
           AppDomain.CurentDomain.GetAssemblies();
    获取当前 对象 所在的 Assembly
           this.GetType().Assembly
    根据路径加载Assembly
          Assembly.LoadFrom(命名空间.类名)
    获取Type对象的方式
    1.通过类 获得 对应
             Type:Type t = typeof(Person)
    2.通过对象 获得
             Type:Type t = p.GetType()
    3.根据类的全名称 获取程序集中定义的类
             Type type = Assembly.GetType(“命名空间.类名”)
    4.获取程序集中定义的所有的public类
             Type[] types = assembly.GetExportedTypes
    5.获取程序集中定义的所有的类型
             Type[] types = assembly.GetTypes()
    获取Type的成员
    属性:
            type.Assembly:获取type所在程序集对象
            type.FullName:获取type对象对应的类的全名称
            type.Name:获取type对象对应类的 名称
            type.IsArray:判断type是否为一个数组类
            type.IsEnum:判断type是否为一个枚举类
    方法:
            type.IsAssignableFrom(Type i):判断type是否实现了接口i
            type.IsSubclassOf(Type father):判断type是否继承了father
            type.IsInstanceOfType(object o):判断o是否为type类的实例

            type.GetFiled(“gender“):获取type中名为gender的字段对象
            type.GetProperty(“Age”):获取type中名为Age的属性对象
            type.GetMethod(“SayHi”):获取type中名为SayHi的方法对象

    反射- FiledInfo字段对象

    static void Main(string[] args)
    {
        Dog dObj=new Dog()
        {
            dogName = "小白",
            dogAge = 1
        };
        Type dType = dObj.GetType();
        //获取字段对象
        FieldInfo fieldDogName = dType.GetField("dogName");
        //获取dObj对象的dogName字段值,即dObj.dogName
        string strName = fieldDogName.GetValue(dObj) as string;
        //设置dObj里dogName字段赋值
        fieldDogName.SetValue(dObj,"小黑");
    
        Console.WriteLine(dObj.dogName);
        Console.ReadKey();
    }

    反射-PropertyInfo属性对象

    static void Main(string[] args)
    {
        Dog dObj = new Dog() {Name = "小白", Age = 1};
        Type dType = dObj.GetType();
        //获取属性对象
        PropertyInfo proName = dType.GetProperty("Name");
        //获取dObj对象的Name属性,即dObj.Name
        string strName = proName.GetValue(dObj) as string;
        //设置dObj里面Name属性值
        proName.SetValue(dObj,"小黑");
    
        Console.WriteLine(dObj.Name);
        Console.ReadKey();
    }

    反射-MethodInfo方法对象

    static void Main(string[] args)
    {
       Dog dObj=new Dog();
        Type dType = dObj.GetType();
        MethodInfo method = dType.GetMethod("Smile");
        //普通调用方法
        object res1 = dObj.Smile("小白");
        //反射调用dObj的Smile方法,即dObj.Smile("小黑")
        //第一个参数是实例对象,第二个参数是方法的参数数组
        object res2 = method.Invoke(dObj, new object[] {"小黑"});
        
        Console.WriteLine(res1+" 
    "+res2);
        Console.ReadKey();
    }

    动态创建对象

    static void Main(string[] args)
    {
        //方法一:通过Activator 动态创建对象
        Type dType = typeof (Dog);
        //调用带两个参数的构造函数
        Dog dogXB = Activator.CreateInstance(dType,new object[]{"小白",1}) as Dog;
        Console.WriteLine(dogXB.Name+"	"+dogXB.Age);
    
        //方法二:使用 构造器 动态创建对象
        Type dTypeXH = typeof (Dog);
        //获得 带两个参数的 构造函数
        ConstructorInfo ctor = dType.GetConstructor(new Type[] {typeof (string), typeof (int)});
        //创建 指定构造函数
        Dog dogXH = ctor.Invoke(new object[] {"小黑", 2}) as Dog;
        Console.WriteLine(dogXH.Name+"	"+dogXH.Age);
        
        Console.ReadKey();
    }
    更多精彩内容请看:http://www.cnblogs.com/2star
  • 相关阅读:
    理解vertical-align
    理解css行高(line-height)
    react 生命周期函数
    react Diff 算法
    React中的虚拟DOM
    无限重启:windows更新之后,在输入密码页面无限重启进入不了系统
    [转]github 上传project代码
    【转】HTTP响应状态码参考簿
    TweenMax—ScrambleText插件 实现类似电脑破译密码的特效
    既然CPU一次只能执行一个线程,那多线程存在的意义是什么?
  • 原文地址:https://www.cnblogs.com/kimisme/p/4337657.html
Copyright © 2020-2023  润新知