【问题标题】:Check if ClassDeclarationSyntax implements a specific interface (Standalone code analysis tool)检查 ClassDeclarationSyntax 是否实现了特定接口(独立代码分析工具)
【发布时间】:2022-01-23 02:54:35
【问题描述】:

在我的 .NET 6 Standalone Code Analysis Tool 中,我有一个 Compilation 实例、一个 SemanticModel 实例和一个 ClassDeclarationSyntax 实例。

我需要知道该类是否实现了特定接口 (MediatR.IRequest<TRequest, TResponse>)

我可以使用字符串匹配来做到这一点,但我不喜欢这样,有没有更好的方法?

private static async Task AnalyzeClassAsync(Compilation compilation, SemanticModel model, ClassDeclarationSyntax @class)
{
    var baseTypeModel = compilation.GetSemanticModel(@class.SyntaxTree);

    foreach (var baseType in @class.BaseList.Types)
    {
        SymbolInfo symbolInfo = model.GetSymbolInfo(baseType.Type);
        var originalSymbolDefinition = (INamedTypeSymbol)symbolInfo.Symbol.OriginalDefinition;
        if (!originalSymbolDefinition.IsGenericType)
            return;
        if (originalSymbolDefinition.TypeParameters.Length != 2)
            return;

        if (originalSymbolDefinition.ToDisplayString() != "MediatR.IRequestHandler<TRequest, TResponse>")
            return;

        // Do other stuff here
    }
}

【问题讨论】:

    标签: c# roslyn


    【解决方案1】:

    我使用这个扩展方法:

    public static class TypeExtensions
    {
      public static bool IsAssignableToGenericType(this Type type, Type genericType)
      {
        if (type == null || genericType == null) return false;
        if (type == genericType) return true;
        if (genericType.IsGenericTypeDefinition && type.IsGenericType && type.GetGenericTypeDefinition() == genericType) return true;
        if (type.GetInterfaces().Where(it => it.IsGenericType).Any(it => it.GetGenericTypeDefinition() == genericType)) return true;
        return IsAssignableToGenericType(type.BaseType, genericType);
      }
    }
    

    像这样使用它:

    var doesIt = typeof(MyClass).IsAssignableToGenericType(typeof(MediatR.IRequestHandler<,>)));
    

    【讨论】:

    • 这就是在普通代码中的做法。我的问题是关于如何在代码分析应用程序中执行此操作,据我所知,您无法访问该类型。
    【解决方案2】:

    获取对接口的引用,然后检查类是否实现它是一种更简洁的方法。

    private static async Task AnalyzeClassAsync(Compilation compilation, SemanticModel model, ClassDeclarationSyntax @class)
    {
        // MediatR.IRequestHandler`2 should be the fully qualified name
        // `2 indicates that the class/interface takes 2 type parameters
        var targetTypeSymbol = compilation.GetTypeByMetadataName("MediatR.IRequestHandler`2");
    
        // ...
    
        var implementsIRequestHandler = originalSymbolDefinition.AllInterfaces.Any(i => i.Equals(targetTypeSymbol))
    
       // Do other stuff here
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2016-09-29
      • 1970-01-01
      • 2018-10-19
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多