【问题标题】:Correct way to check the type of an expression in Roslyn analyzer?在 Roslyn 分析器中检查表达式类型的正确方法?
【发布时间】:2022-02-22 00:52:07
【问题描述】:

我正在用 Roslyn 编写代码分析器,我需要检查 ExpressionSyntax 的类型是 Task 还是 Task<T>

到目前为止,我有这个:

private static bool IsTask(ExpressionSyntax expression, SyntaxNodeAnalysisContext context)
{
    var type = context.SemanticModel.GetTypeInfo(expression).Type;
    if (type == null)
        return false;
    if (type.Equals(context.SemanticModel.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task")))
        return true;
    if (type.Equals(context.SemanticModel.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1")))
        return true;
    return false;
}

它适用于Task,但不适用于Task<int>Task<string>...我可以检查名称和命名空间,但这不切实际,因为我必须检查命名空间的每个“级别”。

有推荐的方法吗?

【问题讨论】:

  • 我有几乎相同的问题,但更笼统地说:如何检查表达式是否匹配任何给定的类型,而不是像这个问题中的特定类型。 See my answer 此处提供完整代码示例

标签: c# .net code-analysis roslyn


【解决方案1】:

检查类型是否为is a generic type,如果是,则使用OriginalDefinition返回未构造的泛型类型。

【讨论】:

  • 谢谢!我错过了我得到的ITypeInfo 实际上是INamedTypeSymbol,所以我看不到IsGeneric 属性。然而ConstructUnboundGenericType 给了我Task<>,而不是Task<TResult>,所以它与我用GetTypeFromMetadataName 得到的类型不匹配。我不得不改用ConstructedFrom 属性。
  • 使用OriginalDefinition——它会给你在所有情况下都匹配GetTypeByMetadataName的类型。在嵌套泛型或泛型方法的情况下,ConstructedFrom 并不是您想要的。
【解决方案2】:

如果您需要符号而不是语法

INamedTypeSymbol nulable = compilation.GetTypeByMetadataName("System.Nullable`1");
INamedTypeSymbol int32 = compilation.GetSpecialType(SpecialType.System_Int32);
INamedTypeSymbol nulableInt = nulable.Construct(int32);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多