问题描述
我使用ReSharper 8 sdk并希望找到特定通用接口的所有继承者,其中通用类型是特定类型。我有,这个问题大部分都在那里,但我只能找到 ICommandHandler< T>
不是我想要的一个实现, ICommandHandler< TestCommand>
这是我有的代码:
foreach(declaredElement.GetPsiServices()中的var psiModule)模块。 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();
$ b 如果我在此行之后提示commandHandlerType:
var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);
我看到该类型被正确指定:
但是当我从这个类型获得 ITypeElement
传入我的搜索时使用这一行
var handlerTypeelement = commandHandlerType.GetTypeElement();
我似乎已经失去了这种类型:
search找到 ICommandHandler< T>
的所有实现。
所以我的问题是,如何创建 ITypeElement
它代表了我想搜索的封闭泛型类型?
或者:我如何搜索返回的集合继承者的类型,它有我开始的类作为泛型类型参数?
解决方案啊,这是有道理的。一个 ITypeElement
是 IDeclaredElement
的一个实例,这意味着它有一个声明 - 例如类或接口声明。所以,当你得到一个代表你的封闭泛型的 IType
时,它由代表泛型类型的 ITypeElement
ICommandHandler
)和一个 ISubstitution
,它表示已解析的泛型类型参数( AnotherCommand
)。当您调用 IType.GetTypeElement()
时,它将返回类型元素/替换对的类型元素部分,这是开放式通用声明元素(因为接口声明可以我认为你可能不得不采取另一种方法,并找到 ITypeHandler< T>的所有继承者(实现者)。
并在消费者中将其过滤掉。传递给使用者的 FindResult
可以向下转换为 FindResultInheritedElement
,这会给你一个声明的元素来表示类实现 ITypeHandler< T>
。您应该能够遍历这些元素的接口以查看它们实现的内容,并且只接受实现正确 T
的查找结果。我认为 TypeElementUtil
在这里可以帮助获取声明元素的所有超类型(基类型+接口)。
I'm using the ReSharper 8 sdk and want to find all inheritors of a particular generic interface, where the generic type is a particular type. I have asked a more general question which got most of the way there, but I am only able to find any implementation of ICommandHandler<T>
and not the one implementation I want, ICommandHandler<TestCommand>
this is the code I have:
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();
}
}
if I tooltip the commandHandlerType after this line:
var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);
I see that the type is correctly specified:
But then when I get the ITypeElement
from this type to pass into my search using this line
var handlerTypeelement = commandHandlerType.GetTypeElement();
I seem to have lost the type:
And so my search finds all implementations of the ICommandHandler<T>
.
So my question is, how do I create the ITypeElement
which represents the closed generic type I want to search for?
Or alternatively: How can I search the returned collection of inheritors for the type which has the class I started with as the generic type parameter?
解决方案 Ah, that makes sense. An ITypeElement
is an instance of IDeclaredElement
, which means it's something that has a declaration - such as a class or interface declaration. So when you get an IType
that represents your closed generic, it's made up of an ITypeElement
that represents the generic type (ICommandHandler
) and an ISubstitution
that represents the resolved generic type parameters (AnotherCommand
). When you call IType.GetTypeElement()
, it will return the type element part of the type element/substitution pair, which is the open generic declared element (because an interface declaration can only ever be open).
I think you might have to take the alternative approach, and find all inheritors (implementors) of ITypeHandler<T>
and filter them down in the consumer. The FindResult
passed to the consumer can be downcast to a FindResultInheritedElement
, which will give you a declared element that represents the class that implements ITypeHandler<T>
. You should be able to walk these elements' interfaces to see what they implement, and only accept those find results that implement the correct T
. I think TypeElementUtil
will help here to get all super types (base types + interfaces) of the declared element.
这篇关于如何在ReSharper插件中创建一个表示封闭泛型类型的`ITypeElement`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!