• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#学习-程序集和反射

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
准备项目
1.新建一个空的解决方案MyProj.sln
2.在该解决方案下,建一个控制台项目P01.csproj
3.在该项目下,自己新建一个类MyFirstClass.cs
查看解决方案MyProj.sln,知道本次要编译哪个项目
查看项目文件P01.csproj(其实就是一个xml文档),可以知道本次程序会编译的类
类库编译成程序集
在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+" \n"+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+"\t"+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+"\t"+dogXH.Age);
    
    Console.ReadKey();
}

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
fatalerrorC1083:无法打开包括文件:“atlsrvres.h”发布时间:2022-07-14
下一篇:
c++读写二进制文件发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap