• .NET拾忆:反射的本质——元数据


    反射主要使用的命名空间:

    System.Reflection
    System.Type
    System.Reflection.Assembly

    本质:元数据

    反射的本质其实是使用元数据;元数据其实就是程序编译出来的特定数据结构的表;当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等;用过c++的可能会类比一下头文件;

    反射的作用就是解析使用这些元数据;上面的几个命名空间就是实现这些解析与使用。

    示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Practice.NET.Reflact
    {
        public class Product
        {
            public string Name { get; set; }
            public decimal Price { get; set; }
    
    
            public Product()
            {
    
            }
    
            public Product(string name, decimal price)
            {
                this.Name = name;
                this.Price = price;
    
            }
    
    
            public void PrintName()
            {
                Console.WriteLine(this.Name);
            }
    
            void PrintPrice()
            {
                Console.WriteLine(this.Price.ToString());
            }
    
            public string GetName(string name)
            {
                this.Name = name;
                return this.Name;
    
            }
            public void GetName()
            {
                PrintName();
            }
    
            public void ShowPrice(ref decimal price)
            {
                this.Price = price;
    
            }
        }
    }
    Product
    using System;
    using System.Reflection;
    
    namespace Practice.NET.Reflact
    {
        public class ReflactTest
        {
            /// <summary>
            /// 基本用法
            /// </summary>
            public void Test()
            {
                //1、-------------------------程序集------------------------
                string path = AppDomain.CurrentDomain.BaseDirectory + "Practice.NET.exe";//;
                Assembly ass = Assembly.LoadFrom(path);
                
                
                //2、--------------------------类--------------------
    
                //第一种方法,在类的构造函数是无参时使用方便,在有参时就不容易实现
    
                object obj1 = ass.CreateInstance("Practice.NET.Reflact.Product");//实例化Person类,返回值是object,通过命名空间及类名得到
                Type myType1 = obj1.GetType(); //得到类的类型
    
                //第二种方法,通过获得类型的构造函数来实例化对象,在构造函数是有参时也容易实现
    
                Type myType2 = ass.GetType("Practice.NET.Reflact.Product");//得到类的类型
    
                ConstructorInfo constructor = myType2.GetConstructor(new Type[0]);//得到myType的构造函数(无参)
    
                object instance2 = constructor.Invoke(null);//调用构造函数来实现实例化类现在先通过调用无参构造函数来实例化类,下面看一下通过反射怎么得到类成员:
    
                //3、--------------------方法-------------------------
    
                MethodInfo method1 = myType2.GetMethod("PrintName");//得到无参公有方法
    
                MethodInfo method2 = myType2.GetMethod("PrintPrice", BindingFlags.Instance | BindingFlags.NonPublic);//得到私有方法
    
                MethodInfo method3 = myType2.GetMethod("GetName", new Type[] { typeof(string) });//得到带参数的公有方法(后面的Type类型可以省略,但如果是重载方法就不能省)
    
                MethodInfo method4 = myType2.GetMethod("GetName", new Type[0]);
    
                MethodInfo method5 = myType2.GetMethod("ShowPrice");//得到参数是ref的的方法
    
                //4、-----------------------------属性------------------
                //得到属性
                PropertyInfo[] propertys = myType2.GetProperties(BindingFlags.Instance | BindingFlags.Public);
    
                PropertyInfo Name = myType2.GetProperty("Name");
                PropertyInfo Price = myType2.GetProperty("Price");
    
                FieldInfo name = myType2.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);//得到字段(全是私有的)
                FieldInfo age = myType2.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);
    
                //设置/读取属性
                Name.SetValue(instance2, "李四", null);//给Name设值,后面的null是对应的索引器
    
                Price.SetValue(instance2, 23M, null);
    
                Name.GetValue(instance2);
    
                //5、----------------特性 myParamAttribute--------------
                //foreach (var item in propertys)
                //{
                    //item.GetCustomAttributes(typeof(myAttribute), true).Length //返回item包含myAttribute特性的数组
    
    
                //}
                
    
    
                //6、----------------调用方法------------
    
                method1.Invoke(instance2, null);
    
                method2.Invoke(instance2, null);
    
                Console.WriteLine(method3.Invoke(instance2, new object[] { "王五" }));//调用有返回值的方法
    
                method4.Invoke(instance2, null);
    
                method5.Invoke(instance2, new object[] { 14M });//调用参数是ref的方法
            }
        }
    }
    ReflactTest
  • 相关阅读:
    hive 之with....as的用法
    hive 之lateral view 函数用法
    linux 之 bash: telnet: command not found...报错
    mysql 之 一个库中所有表复制到另一个数据库中,实现两个表迁移
    mysql 之group by 后取每一组最大的一行值
    kettle 报错 Error converting characters into server's character set. Some character(s) could not be converted.
    mysql 之数据类型转换cast()函数和convert()函数
    hive 之基础知识及查询三
    hive 之基础知识及语法二
    Vue(十)
  • 原文地址:https://www.cnblogs.com/xmai/p/7404464.html
Copyright © 2020-2023  润新知