C#中的映射

C#编译后的文件主要由IL代码和元数据组成,元数据为.NET组件提供了丰富的自描述特性,它使得我们可以在代码运行时获知组件中的类型等重要的信息。C#中这是通过一种称作映射(Reflection)的机制来完成的。

动态类型查询

首先创建一个简单的类型:

namespace ReflectionClass

{

public class MyClass

{

#region Property

private int m_Count = 100;

public int Count

{

get

{

return m_Count;

}

set

{

m_Count = value;

}

}

#endregion

#region Method

public void Print()

{

Console.WriteLine("MyClass.Count = {}", Count);

}

#endregion

}

}

编译后可以得到“ReflectionClass.dll”文件,接下来实现查询类型的测试程序:

namespace TestReflection

{

public class App

{

static void Main(string[] args)

{

Type type = typeof(MyClass); //获取MyClass的类型信息

Console.WriteLine("The Type Name : {0}", type.Name); //获取类型的名字

FieldInfo[] fieldArray = type.GetFields(); //获取所有的公有域

Console.Write("The {0} Fields : ", fieldArray.Length);

foreach (FieldInfo field in fieldArray)

{

Console.Write(field.Name + " ");

}

Console.WriteLine();

PropertyInfo[] propertyArray = type.GetProperties(); //获取所有的公有属性

Console.Write("The {0} Properties : ", propertyArray.Length);

foreach (PropertyInfo property in propertyArray)

{

Console.Write(property.Name + " ");

}

Console.WriteLine();

MethodInfo[] methodArray = type.GetMethods(); //获取所有的公有方法

Console.Write("The {0} Methods : ", methodArray.Length);

foreach (MethodInfo method in methodArray)

{

Console.Write(method.Name + " ");

}

}

}

}

编译后执行,可以得到以下输出:

The Type Name : MyClass

The 0 Fields :

The 1 Properties : Count

The 7 Methods : get_Count set_Count Print ToString Equals GetHashCode GetType

在上面的例子中,首先通过 typeof(MyClass)获得MyClass类的类型信息,当然也可以通过创建对象实例,然后调用对象实例的GetType方法来获得(每个类都从 object根类中继承获得此方法)。在拥有了类型信息(变量type)后,便可以获得其类型的名字、该类型含有的公有域、公有属性、公有方法。注意: 这里C#的映射机制只允许获取类型的公有信息,这符合面向对象的封装原则。其中4个方法(GetHashCode、Equals、ToString、GetType)都是继承自object类的公有方法,而方法get_Count 和set_Count则是实现Count属性的“副产物。实际上,System.Type类各种各样的成员使得我们能够获得几乎所有与类型相关的公有信息。在System.Reflection命名空间下的各个类都可以获得各个编程元素较详细的信息,如方法的参数与返回值、域的类型、枚举的各个值等。

动态创建与调用

实际上映射远不止动态地获知组件的类型信息,它还能在获得类型信息的基础上,在代码运行时进行类型的动态创建与方法的动态调用。

namespace TestReflection2

{

public class App

{

static void Main(string[] args)

{

Assembly assemlby = Assembly.LoadFrom("ReflectionClass.dll"); //装载组件

foreach (var type in assemlby.GetTypes())

{

if (type.IsClass && !type.IsAbstract)

{

MethodInfo[] methodArray = type.GetMethods(); //获得类型的公有方法

object obj = Activator.CreateInstance(type); //创建实例(无参构造器)

foreach (var method in methodArray)

{

if (!method.IsAbstract && !method.IsStatic && method.GetParameters().Length == 0)

{

object ret = method.Invoke(obj, null); //调用实例方法

Console.WriteLine("{0}'s Return : {1}", method.Name, ret);

}

}

}

}

}

}

}

编译后执行,可以得到以下输出:

get_Count's Return : 100

MyClass.Count = 100

Print's Return :

ToString's Return : ReflectionClass.MyClass

GetHashCode's Return : 62476613

GetType's Return : ReflectionClass.MyClass

在上面的例子中给出了被动态调用的方法名字和返回值。其中第二行输出的“MyClass.Count = 100”,它是动态调用方法MyClass.Print()的输出。需要指出的是调用的是类型的公有无参数实例方法。给出组件的名字,应用Assembly.LoadFrom,我们便可以动态地装载组件。 Activator.CreateInstance()允许动态地创建类型(这里只通过无参数的构造器来创建),实际上用它创建出来的类型和用“MyClass obj = new MyClass()”创建出来的类型一样。进而,还可以在查询到的成员的基础上,对它们进行动态调用。

另外,还可以用“Assembly.CreateInstance()”创建实例,从本质上讲,“Assembly.CreateInstance()”就是调用的“Activator.CreateInstance()”。

C# .NET中的 反射的应用的更多相关文章

  1. 详解C#中的反射

    反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B ...

  2. python中的反射

    在绝大多数语言中,都有反射机制的存在.从作用上来讲,反射是为了增加程序的动态描述能力.通俗一些,就是可以让用户参与代码执行的决定权.在程序编写的时候,我们会写很多类,类中又有自己的函数,对象等等.这些 ...

  3. .net中的反射(转载)

    原文地址:http://www.cnblogs.com/Stephenchao/p/4481995.html 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的 ...

  4. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  5. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  6. .Net 中的反射(序章) - Part.1

    引言 反射是.Net提供给我们的一件强力武器,尽管大多数情况下我们不常用到反射,尽管我们可能也不需要精通它,但对反射的使用作以初步了解在日后的开发中或许会有所帮助. 反射是一个庞大的话题,牵扯到的知识 ...

  7. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  8. Go 中的反射要点

    简介 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力.不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型. 类型以及接口 这个基本概念需要清晰,这里不详细展开. ...

  9. 【转】详解C#中的反射

    原帖链接点这里:详解C#中的反射   反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...

  10. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

随机推荐

  1. 二叉树,平衡树,红黑树,B~/B+树汇总

    二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree).这四种树都具备下面几个优势: (1) 都是动态结构.在删除,插入操作的时候,都不需要彻底重建原始的索引树 ...

  2. Oracle Sql优化之报表和数据仓库运算

    1.行转列:有两种写法,一种是case when end写法,另一种写法是pivot(oracle 11g新增) select job, then sal end) as sal10, then sa ...

  3. 交换数组中两个元素的位置,元素包括key和value 一维数组

    /*author: yangyu@sina.cndescription: 交换数组中两个元素的位置,元素包括key和value,具体用法见下面的例子*/$arr = array(11=>'a', ...

  4. springMVC如何访问静态文件

    在进行Spring MVC的配置时,通常我们会配置一个dispatcher servlet用于处理对应的URL.配置如下:<servlet><servlet-name>mvc- ...

  5. Android Studio ADB响应失败解决方法(2CTo.com)

    当启动Android Studio时,如果弹出 adb not responding. you can wait more,or kill "adb.exe" process ma ...

  6. Django: 之Web框架完美解析

    Web框架解析 Web通过Socket来监听客户端,,一旦发现客户发送的信息立刻接受.接受之后在服务端查找客户的请求,找到请求返回给用户,断开.这是一个连接,不断的接收,不断的返回. #!/usr/b ...

  7. zabbix agent自动安装脚本

    #!/bin/bash #desc: used for autoinstall zabbix client #说明:本脚本旨在批量安装zabbix_agent,在一个服务器上放好软件和配置文件,执行本 ...

  8. postgres 错误duplicate key value violates unique constraint 解决方案

    SELECT setval('tablename_id_seq', (SELECT MAX(id) FROM tablename)+1) 主要是:serial key其实是由sequence实现的,当 ...

  9. 并发数据(锁)ReaderWriterLockSlim

    ReaderWriterLockSlim 类 ReaderWriterLockSlim 类支持三种锁定模式:Read,Write,UpgradeableRead.这三种模式对应的方法分别是 Enter ...

  10. CSS实现单行、多行文本溢出显示省略号

    单行显示省略号 overflow: hidden; text-overflow:ellipsis; white-space: nowrap;多行显示省略号 display: -webkit-box; ...