M4N*_*M4N 95 .net reflection plugins .net-assembly
我正在尝试使用类似于此的代码扫描程序集以查找实现特定接口的类型:
public List<Type> FindTypesImplementing<T>(string assemblyPath)
{
var matchingTypes = new List<Type>();
var asm = Assembly.LoadFrom(assemblyPath);
foreach (var t in asm.GetTypes())
{
if (typeof(T).IsAssignableFrom(t))
matchingTypes.Add(t);
}
return matchingTypes;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,在某些情况下,我得到一个ReflectionTypeLoadException调用asm.GetTypes(),例如,如果程序集包含引用当前不可用的程序集的类型.
就我而言,我对导致问题的类型不感兴趣.我正在搜索的类型不需要不可用的程序集.
问题是:是否有可能以某种方式跳过/忽略导致异常但仍处理程序集中包含的其他类型的类型?
Jon*_*eet 125
一个相当讨厌的方式是:
Type[] types;
try
{
types = asm.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
types = e.Types;
}
foreach (var t in types.Where(t => t != null))
{
...
}
Run Code Online (Sandbox Code Playgroud)
尽管如此,这绝对是令人讨厌的.您可以使用扩展方法在"客户端"代码中使其更好:
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
// TODO: Argument validation
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
}
Run Code Online (Sandbox Code Playgroud)
你可能希望将这个return声明移出catch块 - 我不是非常热衷于它自己在那里,但它可能是最短的代码......
swe*_*tfa 22
虽然看起来如果没有在某个时刻收到ReflectionTypeLoadException就无法完成任何事情,但上述答案的局限性在于,任何利用异常提供的类型的尝试仍然会导致导致该类型无法加载的原始问题.
为了克服这个问题,以下代码将类型限制为位于程序集中的类型,并允许谓词进一步限制类型列表.
/// <summary>
/// Get the types within the assembly that match the predicate.
/// <para>for example, to get all types within a namespace</para>
/// <para> typeof(SomeClassInAssemblyYouWant).Assembly.GetMatchingTypesInAssembly(item => "MyNamespace".Equals(item.Namespace))</para>
/// </summary>
/// <param name="assembly">The assembly to search</param>
/// <param name="predicate">The predicate query to match against</param>
/// <returns>The collection of types within the assembly that match the predicate</returns>
public static ICollection<Type> GetMatchingTypesInAssembly(this Assembly assembly, Predicate<Type> predicate)
{
ICollection<Type> types = new List<Type>();
try
{
types = assembly.GetTypes().Where(i => i != null && predicate(i) && i.Assembly == assembly).ToList();
}
catch (ReflectionTypeLoadException ex)
{
foreach (Type theType in ex.Types)
{
try
{
if (theType != null && predicate(theType) && theType.Assembly == assembly)
types.Add(theType);
}
// This exception list is not exhaustive, modify to suit any reasons
// you find for failure to parse a single assembly
catch (BadImageFormatException)
{
// Type not in this assembly - reference to elsewhere ignored
}
}
}
return types;
}
Run Code Online (Sandbox Code Playgroud)
你考虑过Assembly.ReflectionOnlyLoad吗?考虑到您正在尝试做的事情,这可能就足够了。
| 归档时间: |
|
| 查看次数: |
32151 次 |
| 最近记录: |