Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取特定类型的基类型_C#_Roslyn - Fatal编程技术网

C# 如何获取特定类型的基类型

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) {

我正在开发一个C代码分析器,并使用Roslyn(.NET编译器API)

我想检查一下,某个特定的类型是否继承自基类类型

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

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
    将通过设计返回null
    TypeSymbol
    ConvertedSymbol
    ,而不是使用
    SemanticModel.GetDeclaredSymbol

    var-propertyTypeSymbol=context.SemanticModel.GetDeclaredSymbol(propertyDeclaration)作为ITypeSymbol;
    var classTypeSymbol=context.SemanticModel.GetDeclaredSymbol(classDeclaredSymbol)作为ITypeSymbol;
    
    注意,对于一些特殊的声明节点使用
    GetDeclaredSymbol
    :例如
    FieldDeclarationSyntax


  • 谢谢你的帮助,戴夫。但我不是使用系统类型,而是使用自定义(非标准)C#类的
    ITypeSymble
    实例。我不确定这种方法是否适用于这种情况。谢谢。Roslyn提供了使用类型和语法树的其他部分进行操作的机制,而无需生成处理类的实例。还要注意,处理类型可能很繁重/复杂,并且很可能需要将其他对象传递给其构造函数,等等。我想我已经找到了解决此任务的方法。谢谢你的帮助。