1

私は ReSharper 8 SDK を使用しており、ジェネリック型が特定の型である特定のジェネリック インターフェイスのすべての継承者を検索したいと考えています。より一般的な質問をして、ほとんどの方法で解決しましたが、必要な実装ICommandHandler<T>は 1 つではなく、任意の実装しか見つけることができません。ICommandHandler<TestCommand>

これは私が持っているコードです:

foreach (var psiModule in declaredElement.GetPsiServices().Modules.GetModules())
{
    IDeclaredType genericType = TypeFactory.CreateTypeByCLRName("HandlerNavigationTest.ICommandHandler`1", psiModule, theClass.ResolveContext);
    var genericTypeElement = genericType.GetTypeElement();
    if (genericTypeElement != null)
    {                    
        var theType = TypeFactory.CreateType(originalTypeElement);
        var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);
        var handlerTypeelement = commandHandlerType.GetTypeElement();
        solution.GetPsiServices().Finder.FindInheritors(handlerTypeelement, searchDomainFactory.CreateSearchDomain(solution, true),
        inheritorsConsumer, NullProgressIndicator.Instance);
        var inheritedInstance= inheritorsConsumer.FoundElements.First();
        var sourceFile = inheritedInstance.GetSourceFiles().First();
    }
}  

この行の後に commandHandlerType をツールチップすると:

var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);

タイプが正しく指定されていることがわかります。

ジェネリック型が存在!

しかし、ITypeElementこのタイプから取得して、この行を使用して検索に渡すと

var handlerTypeelement = commandHandlerType.GetTypeElement();

タイプを失ったようです:

ジェネリック型が失われました!

したがって、私の検索では、のすべての実装が見つかりますICommandHandler<T>

だから私の質問は、ITypeElement検索したい閉じたジェネリック型を表す をどのように作成するのですか?

または、代わりに、返された継承のコレクションで、ジェネリック型パラメーターとして開始したクラスを持つ型を検索するにはどうすればよいですか?

4

1 に答える 1

1

ああ、それは理にかなっています。AnITypeElementは のインスタンスですIDeclaredElement。これは、クラスやインターフェイスの宣言など、宣言を持つものであることを意味します。したがってIType、閉じたジェネリックを表すを取得するとITypeElement、ジェネリック型を表すICommandHandlerと ( )ISubstitution解決されたジェネリック型パラメーターを表す で構成されますAnotherCommand。を呼び出すとIType.GetTypeElement()、型要素/置換ペアの型要素部分が返されます。これは、オープン ジェネリック宣言要素です (インターフェイス宣言はオープンしかできないため)。

ITypeHandler<T>別のアプローチを取り、すべての継承者 (実装者) を見つけて、コンシューマーでフィルター処理する必要があると思います。FindResultコンシューマに渡される は にダウンキャストできます。FindResultInheritedElementこれにより、 を実装するクラスを表す宣言済み要素が得られますITypeHandler<T>。これらの要素のインターフェイスをたどって、それらが実装するものを確認し、正しい を実装する検索結果のみを受け入れる必要がありますTTypeElementUtilここでは、宣言された要素のすべてのスーパー タイプ (基本タイプ + インターフェイス) を取得するのに役立つと思います。

于 2015-06-26T11:44:15.853 に答える