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
分享到:
相关推荐
压缩包中的"setup.exe"和"帅华的C#实体映射工具V1.0.msi"是工具的安装程序。首先运行"setup.exe"进行安装,然后双击"帅华的C#实体映射工具V1.0.msi"完成安装过程。安装完成后,用户可以通过图形界面连接到SQL SERVER...
在C#编程中,映射(Map)通常指的是对象之间的转换或复制过程,尤其是在需要创建一个新对象作为已有对象副本时。本篇文章将探讨几种不同的C#对象复制方法,并进行性能对比,帮助开发者选择最合适的策略。以下是所...
在.NET框架中,C# LINQ...总的来说,"爆方便_C#linq映射实体_"是一个旨在简化C#开发中数据库操作的实用工具,通过自动化实体映射和提供便捷的LINQ操作,使开发者能更专注于业务逻辑的实现,而不是基础的数据库操作。
在C#中,内存映射是一种高效的数据共享机制,允许一个或多个进程通过映射同一个文件或物理内存区域到进程地址空间,从而实现进程间的数据共享。这种技术广泛应用于需要进行大量数据交换的场景,如数据库缓存、高性能...
在.NET框架4.0中,C#提供了一种高效的数据共享机制,那就是内存映射文件(Memory-Mapped Files)。这个技术允许程序将文件内容映射到进程的虚拟地址空间,从而实现不同进程间的共享数据。在标题和描述中提到的"C# ...
C#语言实现的TCP端口映射` C#语言实现的TCP端口映射` C#语言实现的TCP端口映射`
通过C#调用DOS的NETUSE和当前网络盘的路径,判断当前网络映射盘是否可用,是断开状态还是连接状态。
总的来说,端口映射和端口转发是网络编程中不可或缺的部分,而C#提供了一套强大且灵活的工具来实现这些功能。对于想要深入理解网络通信和提高网络安全性的开发人员来说,研究`Htran`的C#版本源码将是一个有价值的...
在软件开发中,数据持久化是一个关键环节,而将实体类映射到数据库是实现这一目标的常用方式。本文将详细讲解如何使用C#语言配合SQLite数据库进行这项工作,为其他语言和数据库的映射提供参考。 首先,我们需要了解...
C#程序-网络共享盘符映射程序 Process cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.RedirectStandardOutput = true; cmd.StartInfo.RedirectStandardInput = true; cmd.StartInfo....
C# ORM映射 开发及原理 公司内部开发的ORM 源码 禁止商业用途,违者必究!
在C#中调用Windows API时,正确地映射数据类型是确保跨语言互操作性的关键。本篇文章将深入解析给定文档中的数据类型对应关系,帮助开发者更好地理解和应用这些映射规则,从而提高跨平台应用程序的开发效率。 ### ...
- **BOOL (C++)** 与 **Boolean (C#)**:在C++中,`BOOL`通常是一个整型值(通常是`int`),而在C#中则被映射为布尔类型`Boolean`或整型`Int32`。这种差异主要取决于实际的用途和上下文环境。 - **BSTR (C++)** 与...
C#映射网络驱动器是指使用C#语言实现网络驱动器的映射问题,通过调用Windows API中的相关函数和使用StructLayout特性来定义网络资源的结构体,实现网络驱动器的映射。 知识点: 1. 使用DllImport特性调用Windows ...
`char*` 在 C++ 中是指向字符的指针,可以映射到 C# 的 `string`,而 `LPCTSTR` 和 `LPTSTR` 则分别对应 C# 的 `string` 类型,通过 `[MarshalAs(UnmanagedType.LPTStr)]` 进行 marshaling。 对于其他基本类型,`...
本项目“C#编程(纹理映射 OPENGL)”是利用C#语言和OpenGL库来实现三维场景中的纹理映射技术。纹理映射是图形学中的一个重要概念,它将二维图像(纹理)应用到三维模型表面,增加视觉真实感。 首先,我们需要理解...
在这个例子中:我们为内存映射文件定义文件路径 ( filePath) 和大小 ( )。fileSize在本例中,我们正在处理一个 100 MB 的文件。我们使用创建或打开内存映射文件MemoryMappedFile.CreateFromFile。如果该文件不存在,...
当我们在C#中调用Windows API时,由于C#和原生Windows API的数据类型不完全相同,我们需要进行类型映射,以确保数据类型的正确转换。 以下是对给定文件中提到的C#与API类型对照表的详细解析: 1. **BOOL/BOOLEAN**...
总结来说,获取映射驱动器路径在C#中涉及到对Windows API的调用,尤其是`WNetOpenEnum`和`WNetEnumResource`这两个函数。通过这样的方式,开发者可以获取到系统中所有已映射的网络驱动器,并进行相应的操作,如读取...
在C#编程中,数据库字段映射到类代码是一种常见的做法,这有助于简化数据库操作,提高代码的可读性和可维护性。这种映射通常通过ORM(对象关系映射)框架来实现,如Entity Framework、NHibernate或AutoMapper。下面...