C# Roslyn-是给定类型的类或子类的INamedTypeSymbol

C# Roslyn-是给定类型的类或子类的INamedTypeSymbol,c#,roslyn,C#,Roslyn,使用反射,可以非常直接地确定对象是否属于给定的类,方法如下: (t == typeof(MyClass)) || (typeof(MyClass).IsAssignableFrom(t)) 我正试图找出如何使用Roslyn的代码分析API实现同样的功能。我正在使用这样一个循环,它试图在解决方案中找到所有局部变量声明 foreach (var decl in rootNode.DescendantNodes().OfType<LocalDeclarationStatementSyntax&

使用反射,可以非常直接地确定对象是否属于给定的类,方法如下:

(t == typeof(MyClass)) || (typeof(MyClass).IsAssignableFrom(t))
我正试图找出如何使用Roslyn的代码分析API实现同样的功能。我正在使用这样一个循环,它试图在解决方案中找到所有局部变量声明

foreach (var decl in rootNode.DescendantNodes().OfType<LocalDeclarationStatementSyntax>())
                {
                    var symbolInfo = semanticModel.GetSymbolInfo(decl.Declaration.Type);
                    var typeInfo = symbolInfo.Symbol as INamedTypeSymbol;
                    if (typeInfo == null)
                    {
                        continue;
                    }
                    // WHAT DO?

                }
foreach(rootNode.degenantNodes()of type()中的var decl)
{
var symbolInfo=semanticModel.GetSymbolInfo(decl.Declaration.Type);
var typeInfo=symbolInfo.Symbol作为INamedTypeSymbol;
if(typeInfo==null)
{
继续;
}
//你怎么办?
}
我最终试图建立一个列表,列出所有给定类型的变量,或者是给定类型的子类的变量。很容易看出如何将变量类型的名称与我正在寻找的已知类型的名称进行比较,但我还需要处理子类的情况


有没有一种可靠的方法可以让Roslyn做到这一点?

我有一个助手很久以前就在附近检查过这一点。我最近没有与Roslyn联系,所以可能需要有人验证这(仍然)是一个正确的解决方案

foreach (var decl in rootNode.DescendantNodes().OfType<LocalDeclarationStatementSyntax>())
                {
                    var symbolInfo = semanticModel.GetSymbolInfo(decl.Declaration.Type);
                    var typeInfo = symbolInfo.Symbol as INamedTypeSymbol;
                    if (typeInfo == null)
                    {
                        continue;
                    }
                    // WHAT DO?

                }
基本上,一旦拥有了
INamedTypeSymbol
,就可以检查基类的
BaseType
属性以及它实现的所有接口的
AllInterfaces
属性。我记不起后者是在语义还是语法层面上起作用(比如:它是否提供了层次结构中特定类型实现的接口,还是提供了所有接口)。顾名思义就是后者

public static bool ImplementsInterfaceOrBaseClass(this INamedTypeSymbol typeSymbol, Type typeToCheck)
{
    if (typeSymbol == null)
    {
        return false;
    }

    if (typeSymbol.MetadataName == typeToCheck.Name)
    {
        return true;
    }

    if (typeSymbol.BaseType.MetadataName == typeToCheck.Name)
    {
        return true;
    }

    foreach (var @interface in typeSymbol.AllInterfaces)
    {
        if (@interface.MetadataName == typeToCheck.Name)
        {
            return true;
        }
    }

    return false;
}

您可以
compilation.ClassifyConversion(source,target)
并检查结果的
Kind
是否为
ConversionKind.ImplicitReference
在我们使用的Roslyn IDE代码库中。请注意,您需要注意是只包含基类型,还是同时包含接口。另外,您是否关心泛型实例化?

如果您想处理泛型,这将变得非常复杂。我不确定那些
Name
检查是否有效-它们通常不是完全限定的名称。像
FullName
这样的其他属性是否更合适?我不太熟悉它的复杂性。我查看了您详细介绍的扩展方法,但这似乎是一个通用版本,可用于多种不同类型的符号,在这里可能有点过火。ConversionKind是内部的。@AlexZhukovskiy:我们需要包含什么程序集才能获得此扩展方法?链接已断开。我不确定这个方法现在还在同一个类中:你能发布一个更新吗?太晚了,但这里有一个我认为@KevinPilch指向的永久链接: