[英]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.