如何获取特定类型的基本类型

时间:2018-11-08 12:25:50

标签: c# roslyn

我正在使用C#代码分析器,并使用Roslyn(.NET编译器API)。

我想检查一下,特定类型是从基类类型继承的。

例如,假设我们有一个自定义类的层次结构:

TypeA -> TypeB -> TypeC -> TypeD

其中TypeATypeB的父类,TypeBTypeC的父类,而TypeCTypeD的父类。

我创建了一个方法:

    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包含应检查的类型。但是这种方法行不通。代码没有获得符号的父类型。

symbol.BaseType返回两次相同的类类型,然后(在下一次迭代中)得到symbol.BaseType等于null

expectedParentTypeName包含完全限定的类型名称:例如some.namespace.blablabla.TypeC

如何解决此任务?


更新

如上所述,我们假设我们具有一个层次结构:

TypeA -> TypeB -> TypeC -> TypeD

分析后,我得到了一个类型为TypeD的属性,我想检查一下它是否继承自TypeB


更新#2

当我编写代码分析器时,

TypeA -> TypeB -> TypeC -> TypeD类型还不存在。因此,我不能将typeof和其他东西用于这些类型。

它们仅在分析仪将在其中工作的上下文中存在。

我的分析器获取了源代码的一部分,将其识别为类型名称,我想检查一下,该识别出的类型名称是从另一个自定义类型继承而来,该自定义类型是从 custom 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);

propertyTypeInfoclassTypeInfo里面没有任何信息。

enter image description here

3 个答案:

答案 0 :(得分:2)

  1. ITypeSymbol.BaseType正是您需要检索基本类型的地方。如果您的类型是BaseType,接口或指针类型,则System.Object可以为null,并且如果您的Compilation中的语义逻辑有一些麻烦,则它可以是错误类型,这意味着您会错过一些引用,而Roslyn无法完全解析类型。在其他情况下,symbol.BaseType默认情况下应该运行良好。因此,我建议您在Compilation

  2. 中检查您的符号并检查诊断
  3. ITypeSymbol.ToString()将返回由CSharpErrorMessageFormat构造的字符串,该字符串具有FQN类型的样式,足以满足您的问题。如果需要更多,可以将自定义SymbolDisplayFormat传递给ToDisplayString

  4. 对于声明节点,SemanticModel.GetTypeInfo将按设计返回空值TypeSymbolConvertedSymbol,而应使用SemanticModel.GetDeclaredSymbol

    var propertyTypeSymbol = context.SemanticModel.GetDeclaredSymbol(propertyDeclaration) as ITypeSymbol;
    var classTypeSymbol = context.SemanticModel.GetDeclaredSymbol(classDeclaration) as ITypeSymbol;
    

    P.S。请注意,对于某些特殊的声明节点,请使用GetDeclaredSymbol:例如FieldDeclarationSyntax

答案 1 :(得分:1)

只是is吗?

if(DerivedType is BaseType)
{
    //Party time
}

答案 2 :(得分:0)

有多种方法(在其他堆栈问题中称为)在运行时根据类型名创建对象。 (此处有一些有用的代码段:using type returned by Type.GetType() in c#

然后您可以获取symbol的对象,并检查它是否为传入的类型。

if (symbolObject is typeClassWorkedOutAbove)
{
    //do stuff
}