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

时间:2016-09-26 16:53:50

标签: c# roslyn

使用反射,使用类似的东西确定一个对象是否属于某个类非常简单:

(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?

                }

我最终试图建立一个给定类型的所有变量的列表,或者是给定类型的子类。很容易看到我如何将变量类型的名称与我正在寻找的已知类型的名称进行比较 - 但我还需要处理子类的情况。

Roslyn有一种强有力的方法吗?

3 个答案:

答案 0 :(得分:4)

在Roslyn IDE代码库中,我们使用this extension method。请注意,您需要注意是否只包含基类型或接口。另外,你关心泛型实例化吗?

答案 1 :(得分:2)

您可以call compilation.ClassifyConversion(source, target)并检查结果Kind是否为ConversionKind.ImplicitReference

答案 2 :(得分:1)

我有一个帮助,从前一段时间开始检查,检查了这一点。我最近没和罗斯林约会,所以有人可能必须验证这是(仍然)一个合适的解决方案。

基本上,一旦你拥有了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;
}