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()”。
http://www.cnblogs.com/xirihanlin/archive/2009/01/11/1373789.html
分享到:
相关推荐
C#Map映射各个方式性能大比拼,主要测试了各种方式情况下,由一个对象生成另一个相同对象副本,1是列举了常用方式;2是各个方式的性能分析;如果你是喜欢深究其原理的C#开发者,此示例绝对值得你拥有。
通过C#调用DOS的NETUSE和当前网络盘的路径,判断当前网络映射盘是否可用,是断开状态还是连接状态。
htran被好多黑客用來做內网端口映射端口转发。HTran的C#代码版本。
开发过程中经常会遇到实体类保存到数据库的需求。通常就是建好数据库,映射到项目中。这个代码是从代码实体类到数据库(C#+sqlite),其他语言和数据库可用来参考
C# ORM映射 开发及原理 公司内部开发的ORM 源码 禁止商业用途,违者必究!
C#内存映射教程,初始化共享内存方法,关闭共享内存方法,读数据,写数据方法。
C#程序-网络共享盘符映射程序 Process cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.RedirectStandardOutput = true; cmd.StartInfo.RedirectStandardInput = true; cmd.StartInfo....
C# 基于类的内存文件映射,源代码,使用了类定义,写的时候直接创建类,类会自动对应到共享文件,源代码依供参数
自动生成数据表实体(SQL SERVER 2005)
C#语言实现的TCP端口映射` C#语言实现的TCP端口映射` C#语言实现的TCP端口映射`
自动生成C# LINQ 实体映射的工具,可用于linq查询,数据库增删改查
完美实现网络驱动器的映射问题,使用C#完成,代码经过测试。
最近想研究一下反射,先上网找了找资料,几乎大部分都是照抄MSDN的内容,生涩难懂,几乎没说,又找了找,发现一些强人的实例...然后通过某种办法找到这个DLL集合中的某个空间下的某个类的某个成员(不管是公有还是私有)。
摘要:C#源码,系统相关,映射驱动器 C#获取映射驱动器路径,得到被映射的驱动器的路径地址,关于网络映射的源码。
使用C#语言和.net类库实现内存映射技术,实现数据临时存取;
运用C#、opengl做的三维纹理映射,比较有参考价值,希望对大家有帮助
将数据库字段映射成类代码 数据库简单的操作 等等
对象关系映射射(ORM)的研究与基于C#NET的部分实现
C#通过WinIO读取BIOS的版本号 可用于工控行业的测试 程序包里有自己封装好的函数库,里面有对WinIO的操作,使用起来比较简单 这支程序可直接使用,用于工厂测试产品烧录的BIOS版本号 提供了完整的源码,使用时加个...
利用泛型缓存机制;支持对象、集合映射;支持对象深度复制;