[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程html

本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为咱们作些什么,最后介绍几种经常使用的反射的实现方法,经过对反射性特的了解,能够设计出很是有用的基于反射的编程模式。数据库

读前必备:编程

[.net 面向对象编程基础]  (10) 类的成员(字段、属性、方法)设计模式

1.什么是.NET反射?ide

反射是.NET一个重要的特性,《CLR via C#》一书中对.NET反射的解释为:在咱们应用程序中使用元数据来表示存储。编译程序集或模块时,编译器会建立一个类型定义表、一个字段定义表、一个方法定义表以及其它表。而咱们若是想动态调用这些元数据表(或说是解析这些表),或说是为这些元数据建立一个对象模型,这个过程就是反射。函数

简单通俗的说,就是动态调用编译过的程序集中的属性,字段,方法等的过程,就是反射。学习

反射在.NET,经过System.Reflection命名空间中的类来实现。spa

2.反射能为咱们作些什么?.net

这个问题是咱们学习反射的重点,总得知道学习它的好处,才会继续把本文看下去。设计

反射特性,确实是.NET一个很是重要且有用的特性。

A.枚举类型成员

B.实例化新对象

C.执行对象成员

D.查找类型信息

E.查询程序集信息

F.检查应用于某种类型的自定义特性

G.建立和编译新的程序集

H.简化执行时而非编译时绑定的数据的操做。(C# 4.0之后新功能)

此外.NET新版本中容许泛型上的反射.

以上是反射的基本特性,参考了《C#本质论》和《C#高级编程》

基于上面的基本特性,咱们能够设计出不少很是实用的编程模式。

下面列举几种基于反射设计模式下的实例:

A.利用反射创动态建立程序集的API文档。基于反射容许枚举程序集中类型及成员的特性,咱们能够经过反射获取已编译的程序集中的字段方法属性事件和他们的XML注释。从而动态建立程序集的API文档;

B.很是经常使用的反射工厂模式。反射工厂模式在设计模式中比较容易理解,也比较简单。不少代码生成器中就利用这种设计模式完成不一样数据库的反射调用。好比咱们有MsSqlMySqlOracle这三种数据库,在项目设计中,咱们有可能随时换另外一种数据库(固然这只是假设),所以须要同时实现这三种数据库的基础增删改查的类即数据访问类。咱们要切换数据库的时候,只须要在config中更改数据库类型,其余的工做交给反射工厂类去动态调用编译好的程序集中对应的数据库访问方法。

若是没有理解也不要紧,这里只是说明一下反射的应用实例,以便于更有信心的学习反射。反射在设计模式中的应还有不少,这里再也不列举。

3.反射应用基础

上面说了这么多,无非就是先让咱们理解反射能为咱们作些什么,下面进入正题,说一下反射的代码实现。

     下面主要介绍反射的核心类及类成员

     反射的命名空间:System.Reflection

     反射的类大多都在这个命名空间中。

     主要的类: System.Type 

     这个类是反射的核心,其属性方法能够获得运行时的信息。

    Type类派生于System.Reflection.MemberInfo抽象类    

MemberInfo类中的只读属性

属性

描述

备注

Type DeclaringType

获取声明该成员的类或接口的类型

 

MemberTypes  MemberType

获取成员的类型,这个值用于指示该成员是字段、方法、属性、事件、或构造函数

这是一个枚举,它定义了用于表示不一样成员的类型值。这些值包括:MemberTypes.Constructor,   MemberTypes.Method,      MemberTypes.Field,        MemberTypes.Event,      MemberTypes.Property。所以能够经过检查MemberType属性来肯定成员的类型,例如,在MemberType属性的值为MemberTypes.Method时,该成员为方法

Int MetadataToken

获取与特定元数据相关的值

 

Module Module

获取一个表明反射类型所在模块(可执行文件)的Module对象

 

String  Name

成员的名称

 

Type  ReflectedType

反射的对象类型

 

  

Type类的只读属性

属性

描述

Assembly   Assembly

获取指定类型的程序集

TypeAttributes   Attributes

获取制定类型的特性

Type   BaseType

获取指定类型的直接基类型

String  FullName

获取指定类型的全名

bool   IsAbstract

若是指定类型是抽象类型,返回true

bool   IsClass

若是指定类型是类,返回true

string   Namespace

获取指定类型的命名空间

 

Type类的方法

方法

描述

ConstructorInfo[]  GetConstructors()

获取指定类型的构造函数列表

EventInfo[]   GetEvents();

获取指定类型的时间列

FieldInfo[]   GetFields();

获取指定类型的字段列

Type[]   GetGenericArguments();

获取与已构造的泛型类型绑定的类型参数列表,若是指定类型的泛型类型定义,则得到类型形参。对于正早构造的类型,该列表就可能同时包含类型实参和类型形

MethodInfo[]   GetMethods();

获取指定类型的方法列表

PropertyInfo[]   GetProperties();

获取指定类型的属性列表e

MemberInfo[]   GetMembers();

获取指定类型的成员列表

反射还有不少类,这里不一一介绍,详细能够查阅MSDN:

https://msdn.microsoft.com/zh-cn/library/system.reflection.aspx

4.反射实例

下面经过一个实例来学习一下反射最基本的使用方法。

创建一个解决方案,包含两个项目,项目ClassLibrary生成一个DLL(包含两个类),另外一个项目是ReflectionTestGet,用于反射调用类ClassLibrary

第一个项目的两个类以下:

MartialArtsMaster.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary
{
    /// <summary>
    /// 类:武林高手
    /// MartialArtsMaster
    /// </summary>
    class MartialArtsMaster
    {
        /// <summary>
        /// 级别
        /// </summary>
        public int _level = 9;
        /// <summary>
        /// 编号
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }
        /// <summary>
        /// 门派
        /// </summary>
        public string Menpai { get; set; }
        /// <summary>
        /// 武学
        /// </summary>
        public string Kungfu { get; set; }
        /// <summary>
        /// 级别
        /// </summary>
        public int Level
        {
            get
            {
                return _level;
            }

            set
            {
                _level = value;
            }
        }

        /// <summary>
        /// 攻击
        /// </summary>
        /// <param name="kungfu"></param>
        /// <returns></returns>
        public string Attack(string kungfu)
        {
            return "使用用了功夫:" + kungfu;
        }

        public string Kill(string kungfu, string name)
        {
            return "使用用了功夫:" + kungfu + "击杀了" + name;
        }
    }
}
View Code

Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary
{
    /// <summary>
    /// 类:人
    /// </summary>
    class Person
    {
        public string gender { get; set; }
        public string race { get; set; }
        public string Country { get; set; }
        public string Eat(string strCountry)
        {
            switch (strCountry)
            {
                case "美国":

                    return "爱吃西餐";

                case "韩国":

                    return "爱吃泡菜";
                default:
                    return "不知道";
            }
        }
    }
}
View Code

第二个项目调用以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;


namespace ReflectionTestGet
{
    class Program
    {
        static void Main(string[] args)
        {

            Assembly asm = Assembly.LoadFrom("ClassLibrary.dll");  //加载指定的程序集
            Type[] alltype = asm.GetTypes();  //获取程序集中的全部类型列表
            foreach (Type calssName in alltype)
            {
                Console.WriteLine("加载程序的集类名:"+ calssName.Name);  //打印出程序集全部类
                foreach (var field in calssName.GetFields())
                    Console.WriteLine(calssName.Name+"字段有:" + field.Name);  //打印出程序集全部字段,注意只能获取公有字段
                foreach (var pro in calssName.GetProperties())
                    Console.WriteLine(calssName.Name + "属性有:" + pro.Name);  //打印出程序集全部属性
                foreach (var met in calssName.GetMethods())
                    Console.WriteLine(calssName.Name + "方法有:" + met.Name);  //打印出程序集全部方法

            }
            Console.ReadKey();
        }
    }
}
View Code

运行结果以下:

5.本节要点:

本节主要介绍和反射的用途及反射的基本操做类及属性方法,下节继续深刻介绍如何将反射技术应用于实际项目之中。

==============================================================================================  

 返回目录

 <若是对你有帮助,记得点一下推荐哦,若有

有不明白或错误之处,请多交流>  

<对本系列文章阅读有困难的朋友,请先看《.net 面向对象编程基础》>

<转载声明:技术须要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>

.NET 技术交流群:467189533    .NET 程序设计

==============================================================================================   

相关文章
相关标签/搜索