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)标记。否则将不会获取任何方法。

        static void Main(string[] args)
        {
            //创建实例
            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(")");
            }
            //获取类型的属性列表
            var obj1 = sublevelType.GetProperties(BindingFlags.NonPublic|BindingFlags.Instance | BindingFlags.Public);
            //获取类型的成员列表
            var obj2 = sublevelType.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
            //获取类型的构造函数列表
            var obj3 = sublevelType.GetConstructors();
        }

        public class Student
        {
            /// <summary>
            /// 主键
            /// </summary>
            public int id { get; set; }
            /// <summary>
            /// 名称
            /// </summary>
            public string name { get; set; }

            /// <summary>
            /// 年龄
            /// </summary>
            public static int age { get; set; }

            /// <summary>
            /// 无参构造函数
            /// </summary>
            public Student()
            {
                Console.WriteLine("无参构造函数");
            }

            /// <summary>
            /// 有参构造函数
            /// </summary>
            /// <param name="Name">名称</param>
            public Student(string Name)
            {
                name = Name;
                Console.WriteLine(name);
            }

            /// <summary>
            /// 获取名称
            /// </summary>
            /// <param name="Name">名称</param>
            /// <returns></returns>
            public string GetName(string Name)
            {
                name = Name;
                return name;
            }

            /// <summary>
            /// 获取年龄(静态方法)
            /// </summary>
            /// <param name="Age">年龄</param>
            /// <returns></returns>
            public static int GetAge(int Age)
            {
                age = Age + 5;
                return age;
            }
        }

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
01-10 17:56
查看更多