• C#4.0图解教程


    24.1 元数据和反射

    有关程序及类型的数据被成为 元数据他们保存在程序集中

    程序运行时,可以查看其他程序集或其本身的元数据。一个运行的程序查看本身元数据或其他程序的元数据的行为叫做 反射

    反射

    24.2  Type 类

    System.Type精选成员
    Name 属性 返回类型的名字
    Namespace 属性 返回包含类型的命名空间
    Assembly 属性 返回声明类型的程序集。如果类型是泛型,返回定义这个类型的程序集
    GetFields 方法 返回类型的字段列表
    GetProperties 方法 返回类型的属性列表
    GetMethods 方法 返回类型的方法列表

    1.反射概念:

    1.在程序运行时,
           动态 获取 加载程序集
           动态 获取 类型(如类、接口 等)
           动态 获取 类型的成员 信息(如方法,字段,属性等);
    2.在运行时,动态创建类型实例,以及 调用 和 访问 这些 实例 成员;

    namespace _01反射
    {
    class Dog
    {
    public string name;
    public int age;
    private bool gender;

    public string ShoutHi()
    {
    return this.name + "," + this.age + "," + this.gender;
    }
    }

    获取

    image

    调用

    image

    //6.相当于:d2.name=”小白”;

    //7.相当于:d2.ShoutHi();

    2.Assembly 程序集对象

    获取程序集的方式:

    2.1.获得当前 程序域中 所有的Assembly

                   AppDomain.CurrentDomain.GetAssemblies()

    Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();

    ass调用的所有Assembly

    image

     

    2.2.获取当前 对象 所在的 Assembly:

                   this.GetType().Assembly

    //1.获取当前正在运行的 程序集(Assembly)对象
    Assembly ass = this.GetType().Assembly;

    image

     

    2.3.根据路径加载Assembly :

                   Assembly.LoadFrom(assPath)
    image

    3.Type 类型对象

    Type类,程序运行时一个 class 对应一个 Type类的对象。
          通过Type对象可以获得类的所有的定义信息,比如类有哪些属性、哪些方法等

    获得Type对象的方式:
    1.通过类 获得 对应 Type:Type t = typeof(Person)
    2.通过对象 获得 Type:Type t = p.GetType()
    3.根据类的全名称 获取程序集中定义的类:
           Type  type = Assembly.GetType("BLL.Person")

    Type tDog = ass.GetType("_01反射.Dog"); //全名称(带命名空间)

    4.获取程序集中定义的所有的public类:
           Type [] types = assembly.GetExportedTypes()
    5.获取程序集中定义的所有的类型:
           Type [] types = assembly.GetTypes()

    Assembly ass = this.GetType().Assembly;
    //获取此程序集中定义的公共类型,这些公共(public)类型在程序集外可见. (ispublic = true)
    Type[] types = ass.GetExportedTypes();
    // 获取此程序集中定义的所有类型
    Type[] tyoe = ass.GetTypes();

    //1.通过类 直接过去 类型对象
    Type t2 = typeof(Dog);
    //2.通过对象 来获取 类型对象
    Type t3 = this.GetType();

    image

    案例:笔记本插件开发

    SNAGHTML14d0eb6

    plugs文件夹

    image

    namespace C02记事本插件
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    makeBrntBll();
    }

    //读取程序集,并生成插件
    public void makeBrntBll()
    {
    //1.加载正在运行程序的物理路径
    string strRunAss = this.GetType().Assembly.Location;

    //2.获取程序集坐在文件夹,并转换成插件文件夹路径
    string AssPath = Path.GetDirectoryName(strRunAss)+"\plugs";

    //3.扫描插件文件夹里面的所有程序集文件
    string[] strDrictoryPath = Directory.GetFiles(AssPath, "*.dll");

    //4.遍历程序集文件 路径,并加载到内存中
    foreach (var strItem in strDrictoryPath)
    {
    //4.1根据路径 加载到内存中
    Assembly ass = Assembly.LoadFrom(strItem);

    //4.2判断程序集中是否有插件类

    //4.3创建插件按钮
    ToolStripMenuItem menuItem = new ToolStripMenuItem("发现一个插件");
    this.插件扩展ToolStripMenuItem.DropDownItems.Add(menuItem);
    }
    }
    }
    }

    image

    结果:

    SNAGHTML14f7f53

    4.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.GetMethod("SayHi")

    获取type中名为 SayHi 的方法对象

    type.GetProperty("Age") 获取type中名为 Age 的属性对象

    5.FieldInfo 字段对象

    FieldInfo类 代表某个类中的一个成员字段(类的全局变量)

    public class Dog
    {
    public string dogName;
    public int dogAge;
    }

    操作 对象 的字段

                Dog dObj = new Dog() { dogName = "小花", dogAge = 1 };
                //dogName:小花,dogAge:1
                Console.WriteLine(string.Format("dogName:{0},dogAge:{1}",dObj.dogName,dObj.dogAge));
                
                Type dType = dObj.GetType();//获取类型
                FieldInfo fiDN = dType.GetField("dogName"); //获取字段对象
    
                //相当于string strName = dObj.dogName;
                string strName = fiDN.GetValue(dObj).ToString(); //获取dObj的dogName字段值,strName=“小花”
                fiDN.SetValue(dObj, "小白"); //设置dObj里的dogName字段值
                //dogName:小白,dogAge:1
                Console.WriteLine(string.Format("dogName:{0},dogAge:{1}", dObj.dogName, dObj.dogAge));

    6.PropertyInfo 属性对象

    PropertyInfo类 代表某个类中的一个属性

    public class Dog
    {
    public string Name{get;set;}
    public int Age{get;set;}
    }
    操作 对象 的属性
    Dog dObj = new Dog() { Name = "小花", Age = 1 };
                Console.WriteLine(string.Format("dogName:{0},dogAge:{1}", dObj.Name, dObj.Age));
    
                Type dType = dObj.GetType();
                PropertyInfo piN = dType.GetProperty("Name"); //获取属性对象
                string strName = piN.GetValue(dObj, null).ToString(); //获取dObj的Name属性值
                piN.SetValue(dObj, "小白", null); //设置dObj里的Name属性值
                Console.WriteLine(string.Format("dogName:{0},dogAge:{1}", dObj.Name, dObj.Age));
     
     
    7.MethodInfo 方法对象
    MethodInfo类 代表某个类中的一个方法
    public class Dog
    {
    public string Smile(string name)
    {
    return "一只会笑的狗:"+name;
    }
    }

    调用 对象 的方法

    Dog dObj = new Dog();
                Type dType = dObj.GetType();
                MethodInfo method = dType.GetMethod("Smile"); //获取方法对象
    
                object res1 = dObj.Smile("小五~~");//*普通调用方法
                object res2 = method.Invoke(dObj, new object[] { "小白" }); //*反射调用dObj的Smile方法
                Console.WriteLine(string.Format("res1:{0},
    res2:{1}", res1, res2));

    第一个参数是实例对象,第二个参数是方法的参数数组,如果没有参数设置为null
    问:如果第一个参数传 null 呢?

    image
     

    8.动态创建对象

    image

    1.object res =Activator.CreateInstance(Type type)
    会动态调用类的无参构造函数创建一个对象
          返回值就是创建的对象,如果类没有无参构造函数就会报错。

    2.使用 构造器 创建

     
    //构造函数
            //public Dog(){}
            public Dog(string name, int age){
                this.Name = name;
                this.Age = age;
            }
    Type dType = typeof(Dog);//获取 Dog类 类型 对象
                //获取 构造器 对象(根据 参数列表的 参数类型 数组 获取)
                ConstructorInfo cotr = dType.GetConstructor(new Type[] { typeof(string), typeof(int) });
                object resValue = cotr.Invoke(new object[] { "小白", 2 }); //调用指定参数的实例所反映的构造函数cotr
                Console.WriteLine(string.Format("Name:{0},Age:{1}", ((Dog)(resValue)).Name, ((Dog)(resValue)).Age));
    image
    案例:
    Cat.cs
        class Cat
        {
            public string name;
            public int age;
            //构造函数
            public Cat(string name, int age)
            {
                this.name = name;
                this.age = age;
            }
        }

    image

    9.调用对象私有成员

    Person p1 = new Person(); 
    Type type = p1.GetType();
    //BindingFlags.Instance表示是实例方法,也就是不是static方法
    MethodInfo mHaha = type.GetMethod("Haha",BindingFlags.NonPublic | BindingFlags.Instance);
    mHaha.Invoke(p1, null);

    作者:唐三三
    出处:http://tangge.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    星辰小队针对于软件“星遇”的10天冲刺——第8天
    星辰小队针对于软件“星遇”的10天冲刺——第7天
    周周总结——时时更新(第4学期,第11周)
    星辰小队针对于软件“星遇”的10天冲刺——第6天
    星辰小队针对于软件“星遇”的10天冲刺——第5天
    对于文章的字母、单词、短语,(无用词表)的检索Java代码实现
    星辰小队针对于软件“星遇”的10天冲刺——第4天
    图片保存到相册
    心情不好
    NSString和data转换
  • 原文地址:https://www.cnblogs.com/tangge/p/3440605.html
Copyright © 2020-2023  润新知