分享

.NET(C#):不仅仅有Assembly.GetTypes(),试试Module.FindType...

 Kliine 2016-08-29

从程序集中获取类型,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来提问.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多