类库探源-反射机制

导读

1、什么是反射

2、反射的基石——元数据

3、用ildasm.exe 查看元数据

4、System.Reflection 命名空间下需关注的成员

5、获取 Type 实例的方式

6、晚绑定与System.Activator 类


什么是反射

在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。这是Wiki的解释。C#和Java都支持反射,主流的C#和Java框架中都大量应用了反射。反射的主要应用场景如下:

1、使用反射来动态分析来探索程序集中的类型(ildasm.exe 和 ILSpy 等反编译工具)

2、晚绑定

3、Attribute

4、访问某个类的私有成员

5、CLR在执行某些操作是会用到反射机制如:序列化对象时会用到反射、GC用反射构造引用树、指类型的Equal()方法使用反射逐一比较相应字段等

 

 

反射的基石——元数据

上一节说明了反射的定义以及反射的主要应用场景。那么为什么C#和Java会有反射机制?或者说是不是所有编程语言都有反射机制?要回答这些问题,我们就必须谈到反射的基石——元数据。

什么是元数据?

元数据是描述数据的数据(MetaDat is data about data)。这个定义看着可能比较模糊,以C#为例来说,元数据就是记录类、结构以及成员变量的一个数据结构。

 

 

用ildasm.exe 查看元数据

上一节对于元数据的定义可能比较模糊,这一节我将一个例子结合 ildasm.exe 工具谈下元数据

using System;

class DemoLib
{
    private string _name;
    public string Name
    {
        get{return _name;}
        set{_name = value;}
    }

    public void Print()
    {
        Console.WriteLine(Name);
    }
}

csc /t:library DemoLib.cs

用 Ildasm.exe 打开刚才生成的 DemoLib.dll ,按住 Ctrl +M 得到当前程序集的元数据信息如图所示

我们细看下这个 MetaInfo

TypeDef #n、TypeRef #n、Assembly 、AssemblyRef #n、User Strings

上面的5个地方是我们需要重点看的

TypeDef #n        代表类型定义 n是正整数(下同)

TypeRef #n         代表类型引用(当前类型引用的类型)

Assembly            当前程序集的信息

AssemblyRef #n   当前程序集引用的程序集信息

User Strings        当前程序集用到的字面字符串值

我们主要看下 TypeDef 下的内容

Field #1 (04000001)          类型中定义的字段

Method #1 (06000001)     类型中定义的方法

Property #1 (17000001)   类型中定义的属性

元数据中记录类型数据,这也就是为什么元数据被称为描述数据的数据。

System.Reflection 命名空间下需关注的成员

System.Reflection 命名控件提供了与反射机制相关的成员

类型 作用
Assembly 该抽象类包含了许多静态方法,通过它可以加载、了解和操纵一个程序集
MemberInfo 该类是抽象基类,它为EventInfo、FieldInfo、MethodInfo和PropertyInfo类型定义了公共的行为
MethodInfo 该抽象类包含给定方法的信息

下图简要说明了反射的一些过程

 

 

获取 Type 实例的方式

由上图可知,获取一个对象的Type实例是反射机制的核心操作。在C#中一共提供了4中获取Type实例的方法,现归纳如下

1、使用 System.Object.GetType() 获得 Type实例

显而易见,想要使用这个方法,必须得到类型的编译时信息,并且在内存中有类型实例

2、使用 typeof() 得获得Type 实例

需要提供类型的编译时信息, typeof 需要的是类型的强类型名称,而不是文本信息

3、使用 System.Type.GetType() 获得 Type实例

通过调用 System.Type 类的静态方法 GetType() 指定类型的完全限定名,获得Type实例,采用这种方法,我们不需要编译时指定类型信息,System.Type.GetType() 方法有多个重载方法,详细信息查看MSDN

4、使用 Assmbly.GetType( ) 获得Type实例

第四种是最常用的,先加载dll获得程序集实例,在通过程序集实例获得对应类型信息

 

 

晚绑定与System.Activator 类

晚绑定是一种创建一个给定类型的实例并在运行时调用其成员,而不需要在编译时知道它存在的一种技术。通过这种方法使我们的系统扩展性加强

System.Activator 类提供了 创建实例的方法 CreateInstance() 这个方法有很多重载方法详见MSDN

我们来看一个反射实例

using System;
namespace XXX.Common.Lib
{
    public class TestLib
    {
        public TestLib()
        {
            Console.WriteLine("TestLib Ctor.");
        }

        public int Sum(int a,int b)
        {
            Console.WriteLine("Method TestLib.Sum() Invoked");
            return a+b;
        }
    }
}

csc /t:library Lib.cs

得到 Lib.dll

我们在写一个 App.cs 通过反射的方式加载 Lib.cs 中的Sum 方法

using System;
using System.Reflection;

class App
{
    static void Main()
    {
        Assembly assmbly = Assembly.LoadFrom("Lib.dll"); // LoadFrom("FileName.dll")  Load(FileName)
        Type type = assmbly.GetType("XXX.Common.Lib.TestLib");
        object obj = Activator.CreateInstance(type);     // 进入 XXX.Common.Lib.TestLib 构造器

        MethodInfo mi = type.GetMethod("Sum");
        object[] pars = new object[]{1,2};
        int result = 0;
        result = (int)mi.Invoke(obj,pars);
        Console.WriteLine(result);
    }
}

csc app.cs

运行结果

 

本文完

时间: 2024-08-07 08:37:55

类库探源-反射机制的相关文章

Java 核心类库之反射机制

1:什么是反射机制? 2:反射机制它可以做什么呢? 3:反射机制对应的API又是什么? 1):通过反射机制来获取一个对象的全限定名称(完整包名),和类名: 2):实例化Class对象 3):获取对象的父类与实现的接口 4):获取类中的所有的方法或者单个方法 5):使用反射调用方法 && 使用反射调用静态方法 6):使用反射调用数组参数 7):使用反射,动态拷贝数组 7):获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器 8):使用反射调用构造器---->创建对象

java 反射机制:运行时的类信息(为框架服务的Bug存在)

反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 换一种引出反射的说法是:当通过反射与一个未知的类型的对象打交道是,JVM只是简单地检查这个类,看它是属于哪个特定的类(就想RTTI那样).在用它做其他事情之前必须先加载那个类的Class对象.因此,那个类的.class文件对于JVM来说必须是可获取的:那么在本地机器上,要么通过网络获得

Java基础知识——类装载器与反射机制

类装载器ClassLoader 类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示的对象组件. 类装载器把一个类装入JVM中,要经过三步: 1.装载:查找和导入Class文件: 2.链接:执行校验.准备和解析(解析是可以选择的): 3.初始化:对类的静态变量.静态代码块执行初始化工作: 类装载工作由ClassLoader及其子类负责.JVM在运行时会产生三个ClassLoader:根装载器.ExtClassLoader(扩展类装载器)和AppClassLoader(系统类装载器). 根装

Java RTTI机制与反射机制

1.1 什么是RTTI? 维基百科的定义:In computer programming, RTTI (Run-Time Type Information, or Run-Time Type Identification) refers to a C++ mechanism that exposes information about an object's data type at runtime. Run-time type information can apply to simple d

[Java开发之路](14)反射机制

1. Class类 普通对象构造方式: // 创建Book实例对象 Book book = new Book(); 对于Class的实例对象如何构造呢? Class的构造函数是私有的,只有JVM才能创建实例对象 // Class的构造函数是私有的,只有JVM才能创建Class实例对象 Class class1 = new Class(); // 错误 public final class Class<T> implements java.io.Serializable, java.lang.r

深入理解Java类型信息(Class对象)与反射机制(干货)

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/70768369 出自[zejian的博客] 本篇主要是深入对Java中的Class对象进行分析,这对后续深入理解反射技术非常重要,这篇有点偏向内功类文章,主要内容如下: 深入理解Class对象 RRTI的概念以及Class对象作用 Class对象的加载及其获取方式 Class对象的加载 ClassforName方法 Class字面常

java反射机制剖析(二)— Class Loader

上一篇博客简要的提了一下java反射机制中涉及到的一些相关知识,那么ClassLoader就是其中之一.本篇博客就详细的对ClassLoader做一个相对深入的了解.作为了解需要知道的是,其实类类型(Class Class)是和ClassLoader分不开的,因为ClassLoader需要的信息是由它提供的.类类型将在下一篇博客介绍. 简介 ClassLoader是负责加载类的对象,作用是根据Jvm请求提供的类信息,将请求的类加载的内存中或者说加载到Jvm中.另外,每一个类的Class对象(注意

C#反射机制介绍

反射的定义:审查元数据并收集关于它的类型信息的能力.元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等.System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码 System.Reflection.Assembly System.Reflection.MemberInfoSystem.Reflection.EventInfoSystem.Reflection.FieldInfo

java&amp;nbsp;反射机制

转自http://www.iteye.com/topic/1123081 Java语言允许通过程序化的方式间接对Class进行操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数.属性和方法等.Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能,这就为使用程序化方式操作Class对象开辟了途径. 简单实例 我们将从一个简单例子开始探访Java反射机制的征程,下面的Car类拥有