.net core 反射的介绍与使用

  1. 概述反射

  • 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象。 
  •  反射机制允许程序在执行过程中动态地添加各种功能。  

  2. Type类的介绍 

  • 是BCL(基底类别库)声明的一个抽象类,所有它不能被实例化
  • 对于程序中用到的每一个类型,CLR(公共语言运行时)都会创建一个包含这个类型信息的Type类型的对象
  • 程序中用到的每一个类型都会关联到独立的Type类型的对象
  • 不管创建的类型有多少个实例,只有一个Type对象会关联到所有这些实例

    2.1 Type类的部分常见成员

    成员成员类型描述
    Name属性返回类型的名字
    FullName属性返回数据类型的完全限定名(包括命名空间名)
    NameSpace属性返回包含数据类型声明的命名空间
    Assembly属性返回声明类型的程序集。如果类型是泛型的,返回定义这个类型的程序集
    GetConstructor(), GetConstructors()方法返回ConstructorInfo类型,用于取得该类的构造函数的信息
    GetEvent(), GetEvents()方法返回EventInfo类型,用于取得该类的事件的信息
    GetField(), GetFields()方法返回FieldInfo类型,用于取得该类的字段(成员变量)的信息
    GetInterface(), GetInterfaces()方法返回InterfaceInfo类型,用于取得该类实现的接口的信息
    GetMember(), GetMembers()方法返回MemberInfo类型,用于取得该类的所有成员的信息
    GetMethod(), GetMethods()方法返回MethodInfo类型,用于取得该类的方法的信息
    GetProperty(), GetProperties()方法返回PropertyInfo类型,用于取得该类的属性的信息

  3. 如何获取Type类型

   3.1GetType()和typeof() 方法 两者都是返回Syetem.Type的引用。(private和protected修饰的成员也可以访问到)

       3.1.1 GetType()

              1.GetType()是从Syetem.object中基础的方法。

              2.GetType()必须要通过类型的实例点出这个方法。

       3.1.2 typeof()

              1.typeof(xx)是公开的运算符。

              2.typeof(xx)中xx只能是int,string 等类型及自定义类型,不能是实例。

      3.2 不同点

            1.GetType()返回的是Type(类型)

               2.typeof(xx) 返回的是xx Class(类)的类型

 1  //实例一个用户类
 2             User user = new User();
 3             //GetType()方法
 4             Type getType = user.GetType();
 5             //typeof(xx) 方法
 6             Type typeOf = typeof(User);
 7             //判断是否相等
 8             if (getType == typeOf)
 9             {
10                 //这里相等
11                 Console.WriteLine("我在这");
12             }

 4.Type类方法        

  1: 一旦有了Type对象就可以使用GetMethodInfo()方法获取此类型支持的方法列表。该方法返回一个MethodInfo 对象数组,MethodInfo对象描述了主调类型所支持的方法,他位于System.Reflection命名空间中

  2: MethodInfo类派生于MethodBase抽象类,而MethodBase类继承了MemberInfo类。因此我们能够使用这三个类定义的属性和方法。例如,使用Name属性得到方法名称。这里有两个重要的成员:

  3: ReturnType属性 :为Type类型的对象,能够提供方法的返回类型信息 GetParameters()方法 :返回参数列表,参数信息以数组形式保存在PatameterInfo对象中。PatameterInfo类定义了大量描述参数信息的属性和方法。这里也列出两个常用的属性 :Name(包含参数名称信息的字符串),ParameterType(参数类型的信息)。

//创建实例
            Sublevel sublevel = new Sublevel();
            //获取类型
            Type sublevelType = sublevel.GetType();
            //获取类型的方法列表
            //BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public 这个有一个注意点
            //实际上至少要有Instance(或Static)与Public(或NonPublic)标记。否则将不会获取任何方法。
            MethodInfo[] obj = sublevelType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
            //遍历所有的方法
            foreach (MethodInfo item in obj)
            {
                //返回方法的返回类型
                Console.Write(item.ReturnType.Name);
                //返回方法的名称
                Console.Write(" "+item.Name+"(");
                //获取方法的返回参数列表
                ParameterInfo[] parameterss = item.GetParameters();
                foreach (var parameters in parameterss)
                {
                    //参数类型名称
                    Console.Write(parameters.ParameterType.Name);
                    //参数名称
                    Console.Write(" "+parameters.Name+",");
                }
                Console.WriteLine(")");
            }

 

执行的结果,获取了所有的方法,包括了方法的方法名称,方法的返回类型,方法参数列表。

5.方法的使用

    前面我们讲了放的显示,但是只能看到不能用就不好了呀!!!

    5.1:GetMethods()方法的另一种形式

        这种形式可以制定各种标记,已筛选想要获取的方法。他的通用形式为:MethodInfo[] GetMethods(BindingFlags bindingAttr)BindingFlags是一个枚举,枚举值有(很多只列出4个吧)

  1. Instance:获取实例方法
  2. NonPublic: 获取非公有方法
  3. Public: 获取共有方法
  4. Static:获取静态方法

        GetMethods(BindingFlags bindingAttr)这个方法,参数可以使用or把两个或更多标记连接在一起,实际上至少要有Instance(或Static)与Public(或NonPublic)标记。否则将不会获取任何方法。del.GetType();

 

public static void Method<T>(T model) {
            //获取泛性的Type类型
            Type objType = model.GetType();
            //获取泛性的方法列表
            MethodInfo[] mthodInfos = objType.GetMethods();
            //循环方法
            foreach (var item in mthodInfos)
            {
                //获取方法的所有参数列表
                var parameters = item.GetParameters();
                //过滤没用方法
                //1:查看是不是有参数的方法
                //2:查看这个方法的返回类型是不是我们想要的
                //3:查看这个方法的返回类型是不是我们想要的
                if (parameters.Any() && 
                    parameters[0].ParameterType == typeof(int) &&
                    item.ReturnType != typeof(void))
                {
                    //调用方法
                    object[] parametersObj = new object[] { 5 };
                    //调用实例方法
                    //第一个参数是我们的实体,后面是我们的参数(参数是一个数组,多个参数按照顺序来传递,没有参数可以为null)
                    //如果我们的方法是一个静态方法 ,这个参数可以为null (不是静态的就会报错)
                    Console.WriteLine(item.Invoke(model, parametersObj));
                }
            }
        }

 

 
 

 

 

6.DataTable转Model(List)

   在刚刚学.net 的时候,我们从数据库查询出一个DataTable的时候想要转成Model或者LIst的时候我们需要手动的写遍历,超级麻烦(在没有接触MVC的时候我就是)

 /// <summary>
    /// DataTable转换
    /// </summary>
    public class TransitionDataTable
    {
        /// <summary>
        ///  DataTable转换模型
        /// </summary>
        /// <typeparam name="T">模型类型</typeparam>
        /// <param name="obj">模型</param>
        /// <param name="data">数据行</param>
        /// <returns></returns>
        public T DataSetBindModel<T>(T obj, DataTable data) where T : class, new()
        {
            T result = new T();
            foreach (DataRow item in data.Rows)
            {
                result = assignmentClass(obj, item);
            }
            return result;
        }

        /// <summary>
        /// DataTable转换List
        /// </summary>
        /// <typeparam name="T">模型类型</typeparam>
        /// <param name="obj">模型</param>
        /// <param name="data">数据行</param>
        /// <returns></returns>
        public List<T> DataSetBindList<T>(T obj, DataTable data) where T : class, new()
        {
            List<T> result = new List<T>();
            foreach (DataRow item in data.Rows)
            {
                result.Add(assignmentClass(obj, item));
            }
            return result;
        }

        /// <summary>
        /// DataRow 转换成模型
        /// </summary>
        /// <typeparam name="T">模型类型</typeparam>
        /// <param name="obj">模型</param>
        /// <param name="row">数据行</param>
        /// <returns></returns>
        private T assignmentClass<T>(T obj, DataRow row) where T : class, new()
        {
            if (obj == null)
            {
                obj = new T();
            }
            Type type = obj.GetType();
            //得到类型的所有属性,也就是表对应的实体模型的所有属性
            //嗮选一下只要公开的
            PropertyInfo[] properts = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            if (properts.Any())
            {
                foreach (PropertyInfo item in properts)
                {
                    if (row.Table.Columns.IndexOf(item.Name) != -1)
                    {
                        if (row[item.Name] != null && row[item.Name] != DBNull.Value)
                        {
                            item.SetValue(obj, row[item.Name]);
                        }
                    }
                }
            }
            return obj;
        }
    }
View Code

调用

static void Show()
        {
            DataTable data = new BDHelper().GetData("select  *  from  Jack_News_TNews");
            News news = new News();
            var list = new TransitionDataTable().DataSetBindList(news, data);
        }

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值