利用.NET反射检查可空引用类型
.NET 6 引入了 NullabilityInfoContext
API,专门用于处理此任务。
.NET 6之前的方案
在 NullabilityInfoContext
API出现之前,您可以手动检查属性来确定可空性:
<code class="language-csharp">public static bool IsNullable(PropertyInfo property) => IsNullableHelper(property.PropertyType, property.DeclaringType, property.CustomAttributes); public static bool IsNullable(FieldInfo field) => IsNullableHelper(field.FieldType, field.DeclaringType, field.CustomAttributes); public static bool IsNullable(ParameterInfo parameter) => IsNullableHelper(parameter.ParameterType, parameter.Member, parameter.CustomAttributes); private static bool IsNullableHelper(Type memberType, MemberInfo? declaringType, IEnumerable<CustomAttributeData> customAttributes) { // 检查属性本身的 [Nullable] 属性。 var nullable = customAttributes.FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); if (nullable != null && nullable.ConstructorArguments.Count == 1) { // 检查第一个参数的值(表示可空性上下文的字节)。 var args = (ReadOnlyCollection<CustomAttributeTypedArgument>)nullable.ConstructorArguments[0].Value!; if (args.Count > 0 && args[0].ArgumentType == typeof(byte)) { return (byte)args[0].Value! == 2; // 2 代表“可空”。 } } // 检查封闭类型的 [NullableContext] 属性。 for (var type = declaringType; type != null; type = type.DeclaringType) { var context = type.CustomAttributes.FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute"); if (context != null && context.ConstructorArguments.Count == 1 && context.ConstructorArguments[0].ArgumentType == typeof(byte)) { // 检查第一个参数的值(表示可空性上下文的字节)。 return (byte)context.ConstructorArguments[0].Value! == 2; } } // 未找到合适的属性,因此返回 false。 return false; }</code>
此方法可以检查 [Nullable]
和 [NullableContext]
属性,并考虑它们的各种形式和含义。但是,它不处理属性嵌入到程序集的情况,这需要对来自不同程序集的类型进行反射专用加载。
其他注意事项
[Nullable]
属性,其中第一个元素表示实际属性,后续元素表示泛型参数。以上是如何使用 .NET 反射确定可空引用类型?的详细内容。更多信息请关注PHP中文网其他相关文章!