反射程序集
在.NET中,程序集是进行部署、版本控制的基本单元。
System.Reflection命名空间下的Assembly类型,代表了一个程序集,并包含了关于程序集的信息。
本文将演示如何获取程序集信息。
获取Assembly对象有很多种方法:
1. 使用Assembly类型提供的静态方法LoadFrom()
2. 使用Assembly类型提供的静态方法Load()
3. 想获得当前代码所在的程序集,可以使用Assembly类型的静态方法GetExecutingAssembly()
4. 在获得一个Type类型实例以后,还可以使用该实例的Assembly属性来获得其所在的程序集
下面代码对上面的4种情况进行演示:
//提供的是程序集的文件名,在将一个程序集添加到项目引用中以后,可以直接写“文件名.dll”
Assembly assembly1 = Assembly.LoadFrom("ReflectionDemo.exe");
//如果想加载一个不属于当前项目的程序集,则需要给出全路径
Assembly assembly2 = Assembly.LoadFrom(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll");
//使用Load()方法的时候,只用提供程序集名称即可,而非程序集的文件名。
Assembly assembly3 = Assembly.Load("ReflectionDemo");
//使用Assembly类型的静态方法GetExecutingAssembly,它返回包含当前执行代码所在的程序集。
Assembly assembly5 = Assembly.GetExecutingAssembly();
//使用Type实例的Assembly属性来获得其所在的程序集
Type t = typeof(int);
Assembly asm = t.Assembly;
一个程序集可能有多个模块(Module)构成,每个模块又可能包含很多的类型。现在看下反射提供了哪些能力让我们获取关于程序集的信息,如表所示(只列出了部分常用的)。
为了方便进行后面的测试,在解决方案中再添加一个Demo类库项目,程序集中只包含一个命名空间Demo,为了体现尽可能多的类型同时又尽量保持简单,其代码如下:
namespace Demo
{
public abstract class BaseClass
{
}
public struct DemoStruct { }
public delegate void DemoDelegate(Object sender, EventArgs e);
public enum DemoEnum
{
terrible, bad, common = 4, good, wonderful = 8
}
public interface IDemoInterface
{
void SayGreeting(string name);
}
public interface IDemoInterface2 { }
public sealed class DemoClass : BaseClass, IDemoInterface, IDemoInterface2
{
private string _name;
public string city;
public readonly string title;
public const string text = "Const Field";
public event DemoDelegate myEvent;
public string Name
{
private get { return _name; }
set { _name = value; }
}
public DemoClass()
{
title = "Readonly Field";
}
public void SayGreeting(string name)
{
Console.WriteLine("Morning :" + name);
}
public class NestedClass { }
}
}
引用Demo项目,添加一个方法AssemblyExplore(),查看Demo项目生成的程序集中定义的全部类型:
public static void AssemblyExplore()
{
StringBuilder sb = new StringBuilder();
Assembly asm = Assembly.Load("Demo");
sb.AppendLine("FullName:" + asm.FullName);
sb.AppendLine("Location:" + asm.Location);
Module[] modules = asm.GetModules();
foreach (Module module in modules)
{
sb.AppendLine("Module:" + module);
Type[] types = module.GetTypes();
foreach (Type t in types)
{
sb.AppendLine(" Type:" + t);
}
}
Console.WriteLine(sb.ToString());
}
运行结果:
可以清楚看出来程序集中的信息。
本文回顾:
加载程序集
程序集的元数据有哪些
代码实现部分