1. ホーム
  2. .net

[解決済み] Assembly.GetTypes()呼び出し時にReflectionTypeLoadExceptionが発生しないようにする方法

2022-10-31 09:29:55

質問

私は、以下のようなコードを使って、特定のインターフェイスを実装している型についてアセンブリをスキャンしようとしています。

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;
}

私の問題は ReflectionTypeLoadException を呼び出したときに asm.GetTypes() を呼び出した場合、例えば、アセンブリに現在利用できないアセンブリを参照する型が含まれている場合などです。

私の場合、問題の原因となる型には興味がありません。私が検索している型は、利用不可能なアセンブリを必要としないのです。

質問は、例外を引き起こす型をどうにかしてスキップ/無視し、アセンブリに含まれる他の型をまだ処理することは可能でしょうか。

どのように解決するのですか?

かなり厄介な方法としては

Type[] types;
try
{
    types = asm.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
    types = e.Types;
}
foreach (var t in types.Where(t => t != null))
{
    ...
}

こんなことをしなければならないのは、確かに煩わしいですが。拡張メソッドを使って、quot;client"コードでよりきれいにすることができます。

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);
    }
}

を移動させたいと思うかもしれません。 return ステートメントをキャッチブロックの外に出したいと思うかもしれません - 私自身はそこにあることをあまり気にしていませんが、それはおそらく が最短のコードです...