从程序集中获取类型,Assembly类中有GetTypes方法,返回全部类型。或者使用GetType(不是object.GetType)方法,返回一个已知的类型。但是,我们考虑一个介于两者之间的问题:既不是只要一个已知名称的类型,也不需要全部类型。我们需要其中的一部分!怎么办?好吧,简单……用Assembly.GetTypes()方法返回的Type数组,自己手动再进行筛选就可以了。这样是可以的,不过有没有其他方法呢?
答案就是:Module.FindTypes. Module这个类代表一个程序集的模块,每一个程序集都至少有一个模块的。“模块”这个概念不被人熟知是因为一般情况下我们都是用单文件程序集,就是一个程序集只包含一个模块。事实上MSIL代码准确的说是放在模块里的,模块加上程序集清单(Assembly Manifest)才总成一个程序集。最后,Module也有自己的GetTypes和GetType方法,用法和Assembly内的一样(事实上,Assembly的GetTypes方法内部调用了Module.GetTypes方法)。
FindTypes方法第一个参数是TypeFilter委托,第二个是一个object。TypeFilter委托返回值是bool。参数1是需要判断的Type对象,参数2是FindTypes的第二个参数,返回true则类型会被放入最终返回值数组。 看一段代码,我们的目的是返回mscorlib.dll中所有以N开始的类型,先使用常用的Assembly.GetTypes: static void Main() { var mscorlib = GetMscorlib(); var types = test(mscorlib); Console.WriteLine(types.Length); foreach (var t in types) Console.WriteLine(t.Name); } static Type[] test(Assembly ass) { List<Type> re = new List<Type>(); foreach (var type in ass.GetTypes()) if (type.Name.StartsWith('N')) re.Add(type); return re.ToArray(); } static Assembly GetMscorlib() { foreach (var ass in AppDomain.CurrentDomain.GetAssemblies()) if (ass.GetName().Name.Equals('mscorlib', StringComparison.OrdinalIgnoreCase)) return ass; throw new Exception('没有找到mscorlib.dll'); } 在.NET 4.0下,输出40个类。
接下来看使用Module.FindTypes方法,方便的是此时就不用用List把需要的Type再加进去,直接调用就返回结果。 把上面的用Assembly.GetTypes的test方法替换成下面用Module.FindTypes的test方法。通过Assembly.GetModules返回全部模块,普通单文件程序集只会返回一个模块。 static Type[] test(Assembly ass) { return ass.GetModules()[0].FindTypes((type, obj) => type.Name.StartsWith('N'), null); } 结果同样输出40个类型。
事实上,Assembly.GetTypes方法内部也用到了Module.GetTypes方法,如下,Assembly.GetTypes源代码: //.NET 4.0 //Assembly.GetTypes源代码: public virtual Type[] GetTypes() { //找到所有模块 Module[] modules = this.GetModules(false); int length = modules.Length; //总长度 int num2 = 0; //创建一个交错数组来保持每个模块的类型 //注意每个模块的类型数量可能不一样,所以用交错数组 Type[][] typeArray = new Type[length][]; for (int i = 0; i < length; i ) { //将每个模块的类型赋值进数组 typeArray[i] = modules[i].GetTypes(); //更新长度 num2 = typeArray[i].Length; } int destinationIndex = 0; //创建返回值 Type[] destinationArray = new Type[num2]; for (int j = 0; j < length; j ) { //将交错数组中的类型拷贝到返回值数组中 int num6 = typeArray[j].Length; Array.Copy(typeArray[j], 0, destinationArray, destinationIndex, num6); destinationIndex = num6; } return destinationArray; } 有任何疑问,可以到Coldfunction来提问. |
|