C# 如何获取特定类型的基类型
我正在开发一个C代码分析器,并使用Roslyn(.NET编译器API) 我想检查一下,某个特定的类型是否继承自基类类型 例如,假设我们有一个自定义类的层次结构:C# 如何获取特定类型的基类型,c#,roslyn,C#,Roslyn,我正在开发一个C代码分析器,并使用Roslyn(.NET编译器API) 我想检查一下,某个特定的类型是否继承自基类类型 例如,假设我们有一个自定义类的层次结构: TypeA->TypeB->TypeC->TypeD 其中TypeA是TypeB的父类,TypeB是TypeC的父类,TypeC是TypeD的父类 我创建了一个方法: bool InheritsFrom(ITypeSymbol symbol, string expectedParentTypeName) {
TypeA->TypeB->TypeC->TypeD
其中TypeA
是TypeB
的父类,TypeB
是TypeC
的父类,TypeC
是TypeD
的父类
我创建了一个方法:
bool InheritsFrom(ITypeSymbol symbol, string expectedParentTypeName)
{
while (true)
{
if (symbol.ToString().Equals(expectedParentTypeName))
{
return true;
}
if (symbol.BaseType != null)
{
symbol = symbol.BaseType;
continue;
}
break;
}
return false;
}
符号
包含应检查的类型。但这种方法行不通。代码未获取符号的父类型
symbol.BaseType
返回相同的类类型两次,然后(在下一次迭代中)我得到symbol.BaseType
等于null
expectedParentTypeName
包含完全限定的类型名:例如some.namespace.blabla.TypeC
我如何解决这个任务
更新 如上所述,假设我们有一个层次结构:
TypeA->TypeB->TypeC->TypeD
经过分析,我得到一个类型为TypeD
的属性,我想检查它是否继承自TypeB
更新#2 当我编写代码分析器时,
TypeA->TypeB->TypeC->TypeD
类型还不存在。所以,我不能对这些类型使用typeof和其他东西
它们将只存在于分析器工作的上下文中
我的分析器获取源代码的一部分,将其识别为类型名,我想检查,该识别的类型名是否继承自另一个自定义类型,该自定义类型是从自定义nuget包导入的
我所拥有的一切——我有用于分析的源代码,以及类、属性、字段等声明中这些自定义类型的名称
更新#3 对于以下代码:
SyntaxNodeAnalysisContext context; // is already initialized
PropertyDeclarationSyntax propertyDeclaration = (PropertyDeclarationSyntax)context.Node;
ClassDeclarationSyntax classDeclaration = (ClassDeclarationSyntax) propertyDeclaration.Parent;
TypeInfo propertyTypeInfo = context.SemanticModel.GetTypeInfo(propertyDeclaration);
TypeInfo classTypeInfo = context.SemanticModel.GetTypeInfo(classDeclaration);
propertyTypeInfo
和classTypeInfo
中不包含任何信息
只是
是
if(DerivedType is BaseType)
{
//Party time
}
有一些方法(在其他堆栈问题中提到)可以在运行时从typename创建对象。(这里有一些有用的代码片段:)
然后,您可以获取符号的对象
,并检查它是否属于传入的类型
if (symbolObject is typeClassWorkedOutAbove)
{
//do stuff
}
itypesymble.BaseType正是您检索基类型所需要的<如果您的类型是System.Object
、interface或pointer类型,那么code>BaseType
可以为空,如果您在编译中遇到语义逻辑方面的一些问题,那么它可能是错误类型,这意味着您错过了一些引用,并且Roslyn无法正确解析类型。在另一种情况下,默认情况下,symbol.BaseType
应该工作得很好。因此,我建议您检查符号并在编译中检查诊断
itypesymble.ToString()
将返回将由构造的字符串,该字符串的FQN类型样式足以满足您的问题。如果需要更多,可以将自定义的SymbolDisplayFormat
传递给ToDisplayString
对于声明节点SemanticModel.GetTypeInfo
将通过设计返回nullTypeSymbol
和ConvertedSymbol
,而不是使用SemanticModel.GetDeclaredSymbol
var-propertyTypeSymbol=context.SemanticModel.GetDeclaredSymbol(propertyDeclaration)作为ITypeSymbol;
var classTypeSymbol=context.SemanticModel.GetDeclaredSymbol(classDeclaredSymbol)作为ITypeSymbol;
注意,对于一些特殊的声明节点使用GetDeclaredSymbol
:例如FieldDeclarationSyntax
)
谢谢你的帮助,戴夫。但我不是使用系统类型,而是使用自定义(非标准)C#类的ITypeSymble
实例。我不确定这种方法是否适用于这种情况。谢谢。Roslyn提供了使用类型和语法树的其他部分进行操作的机制,而无需生成处理类的实例。还要注意,处理类型可能很繁重/复杂,并且很可能需要将其他对象传递给其构造函数,等等。我想我已经找到了解决此任务的方法。谢谢你的帮助。