繁体   English   中英

如果类型是可空引用,我如何检查 Roslyn

[英]How do I check with Roslyn if a Type is a Nullable Reference

我正在尝试使用 roslyn 分析类型声明是否为“可空引用”类型(C#8)

我打算查看TypeSyntex是否为NullableTypeSyntax以及ITypeSymbol.IsReferenceType是否为true

以下代码在大多数情况下都有效,但是当声明的类型是泛型时失败,即List<T>?

void Main()
{
    string text = @"
        #nullable enable
        public class MyClass
        {
            public string? Get() => null;
            public List<string>? GetGeneric() => null;
        }";
    SyntaxTree tree = CSharpSyntaxTree.ParseText(text);
    PortableExecutableReference mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
    CSharpCompilation compilation = CSharpCompilation.Create("RefitCompilation", syntaxTrees: new[] { tree }, references: new[] { mscorlib });
    SemanticModel semanticModel = compilation.GetSemanticModel(tree);

    MethodDeclarationSyntax nonGenericMethodSyntax = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
    ITypeSymbol nonGenericReturnType = semanticModel.GetTypeInfo(nonGenericMethodSyntax.ReturnType).Type;
    bool isNullableTypeReference = nonGenericMethodSyntax.ReturnType is NullableTypeSyntax && nonGenericReturnType.IsReferenceType;
    Console.WriteLine($@"NonGeneric Nullalbe Reference: `{nonGenericMethodSyntax}`
        Is Nullable Type Reference: {isNullableTypeReference}
        Original Definition: {nonGenericReturnType.OriginalDefinition}, 
        IsNullableTypeSyntax: {nonGenericMethodSyntax.ReturnType is NullableTypeSyntax}
        Is Reference Type: {nonGenericReturnType.IsReferenceType}");

    Console.WriteLine();

    MethodDeclarationSyntax genericMethodSyntax = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Last();
    ITypeSymbol genericReturnType = semanticModel.GetTypeInfo(genericMethodSyntax.ReturnType).Type;
    isNullableTypeReference = genericMethodSyntax.ReturnType is NullableTypeSyntax && genericReturnType.IsReferenceType;
    Console.WriteLine($@"Generic Nullalbe Reference: `{genericMethodSyntax}`
        Is Nullable Type Reference: {isNullableTypeReference}
        Original Definition: {genericReturnType.OriginalDefinition}, 
        IsNullableTypeSyntax: {genericMethodSyntax.ReturnType is NullableTypeSyntax}
        Is Reference Type: {genericReturnType.IsReferenceType}");
}

哪个输出

NonGeneric Nullalbe Reference: `public string? Get() => null;`
        Is Nullable Type Reference: True
        Original Definition: string, 
        IsNullableTypeSyntax: True
        Is Reference Type: True

Generic Nullalbe Reference: `public List<string>? GetGeneric() => null;`
        Is Nullable Type Reference: False
        Original Definition: System.Nullable<T>, 
        IsNullableTypeSyntax: True
        Is Reference Type: False

为什么是List<T>? 原始定义System.Nullable<T> 以及如何确定一个类型是否为 Nullable Reference 类型?

这不是一个完整的答案,但我遇到了同样的问题,这是我对事物的解释。

string text = @"
    #nullable enable
    public class MyClass
    {
        public string? Get() => null;
        public List<string>? GetGeneric() => null;
    }";

List<string>? 无效,缺少System.Collections.Generic使用,因此无法确定List<string>的类型。

接下来发生的是未知的List<T>? type 被解释为可空结构,因此我们到达Nullable<List<string>>

这种情况可以通过询问Nullable的基础类型并检查其TypeKind检查,即

((INamedTypeSymbol)type).TypeArguments[0].TypeKind

将产生Error

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM