C#反射机制
在还不太熟悉反射的昨天 ,以为反射很神秘 ,在网上到处找答案 .今天找了段代码敲了一下 ,茅塞顿开 !
其实反射也就那么简单的一回事 !
反射是一种机制 , 通过这种机制我们可以知道一个未知类型的类型信息 .比如 ,有一个对象 a, 这个
对象不是我们定义的,也许是通过网络捕捉到的,也许是使用泛型定义的,但我们想知道这个对象的
类型信息,想知道这个对象有哪些方法或者属性什么的.甚至我们想进一步调用这个对象的方法.关
键是现在我们只知道它是一个对象,不知道它的类型,自然不会知道它有哪些方法等信息.这时我们
该怎么办?反射机制就是解决这么一个问题的. 通过反射机制我们可以知道未知类型对象的类型信息.
再比如,我们有一个 dll 文件,我们想调用里面的类.现在假设这个 dll 文件的类的定义,数量
等不是固定的,是经常变化的.也许某一天你要在这个 dll 里面增加一个类定义.也许你觉得这没什
么问题,现在关键是我们在另一个程序集里面要调用这个 dll ,这是我们的程序必须能够适应这个 dll
的变化,也就是说即使改变了 dll 文件的定义也不需要改变我们的程序集.这时候我们就会使用一个
未知 dll .我们该怎么办?同样,反射机制帮助了我们,我们可以通过反射来实现.
说白了,反射就是能知道我们未知类型的类型信息这么一个东西.没什么神秘可讲!
今天我先讲一个获得程序集信息的例子.
下面我们来举一个例子. 例子的思路是这样的: 我们有一个 dll. 该 dll 里面有许多关于运动的类. 每
一个类记录了一种体育运动的信息.我们在另外一个程序里面要知道这个 dll 的信息:(如果你还不
能明白我的意思,请耐心的照我的步骤把这个过程走一变!)
第一步:我们建一个文件 Sport.cs. 内容如下:
using System; public abstract class Sport { protected string name; public abstract string GetDuration(); public abstract string GetName(); }
咱们用命令" csc /t:library Sport.cs "编译它.
第二步,我们再建一个名为 SomeSports.cs 的文件,内容如下:
using System; public class Football : Sport { public Football() { name = "Football"; } public override string GetDuration() { return "four 15 minute quarters"; } public override string GetName() { return name; } } public class Hockey : Sport { public Hockey() { name = "Hockey"; } public override string GetDuration() { return "three 20 minute periods"; } public override string GetName() { return name; } } public class Soccer : Sport { public Soccer() { name = "Soccer"; } public override string GetDuration() { return "two 45 minute halves"; } public override string GetName() { return name; } }
下面我们用命令" csc /t:library /r:Sport.dll SomeSports.cs "编译该文件.
现在我们有了我们的运动信息 dll 文件.现在我们想通过程序知道里面有哪些类.请进入最后一
步:
第三步:我们创建文件 AssemblyDemo .cs".内容如下:
using System; using System.Reflection; public class AssemblyDemo { public static void Main(string[] args) { int i, j; //========================== //First the command line arguments are evaluated.if there isn't //at least one,a usage message is printed //================================= if (args.GetLength(0) < 1) { Console.WriteLine("usage is AssemblyDemo<library_name>"); } else { //======================== // An Assembly object is obtained from the command line argument //======================== Assembly assembly = Assembly.LoadFrom(args[0]); Type[] types = assembly.GetTypes(); Console.WriteLine(assembly.GetName().Name + "contains the following types"); for (i = 0; i < types.GetLength(0); ++i) { Console.WriteLine("\r(" + i + ") " + types[i].Name); } i = types.Length - 1; Console.Write("make selection(0-" + i + ");"); j = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(); if (types[j].IsSubclassOf(typeof(Sport))) { ConstructorInfo ci = types[j].GetConstructor(new Type[0]); Sport sport = (Sport)ci.Invoke(new Object[0]); Console.WriteLine(sport.GetName() + "has" + sport.GetDuration()); } else { Console.WriteLine(types[j].Name + "is not a sub-class of Sport"); } } } }
咱们用命令" csc /r:Sport.dll AssemblyDemo.cs "编译该文件.
下面我们用"A ssemblyDemo SomeSports.dll "运行该程序.
进一步程序要求我们输入选项, 咱们输入1,就显示了结果: Hockeyhasthree 20 minute periods.
好了,今天就到这里了,下面我将进一步说明如何用反射机制访问对象的类型信息
我不想在这里过多的描述反射的概念。我还是用我自己觉得最简单、最直接的语言来描述反射
——“反射就是一种机制,通过这种机制,我们能知道一些位知程序集的详细信息!”;通过上一篇
我们已经学会如何得到一个未知程序集的相关信息, 接下来我要讲的是如何知道未知程序模块的信息:
模块信息是通过 Module 类访问的。下面通过一个类子,讲解下 Module 类的使用,如果你是
一个用心的程序员,应该了解下 Module 的详细信息。
下面我们写一个新的文件 ModuleDemo.cs 。内容如下:
// 编译命令 csc /r:Sport.dll ModuleDemo.cs
using System; using System.Reflection; public class ModuleDemo { public static void Main(string[] args) { //======================= // Am Module object is obtained representing the // SomeSports.dll library file //======================= Assembly assembly = Assembly.Load("SomeSports"); Module module = assembly.GetModule("SomeSports.dll"); //====================== //Search the module for the type named "Football" Type[] types = module.FindTypes(Module.FilterTypeName, "Football"); if (types.Length != 0) { ConstructorInfo ci = types[0].GetConstructor(new Type[0]); Sport sport = (Sport)ci.Invoke(new Object[0]); Console.WriteLine(sport.GetName() + " has " + sport.GetDuration()); } else { Console.WriteLine("type not found"); } } }
我们用 csc /r:Sport.dll ModuleDemo.cs 编译,然后用 MouduleDemo 运行程序就能看到如下输
出:Football has four 15 minute quarters 。
关于 C# 反射的基础知识,还有一个知识点就是访问未知对象的类型信息。
注:内容来源于网络