问题:
.NET反射能否用于确定类属性是否使用了可空引用类型?
答案:
在.NET 6之前,检查可空引用类型需要手动检查属性:
<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) { // 值类型如果具有底层类型,则为可空类型 if (memberType.IsValueType) return Nullable.GetUnderlyingType(memberType) != null; // 检查属性本身的[Nullable]属性 var nullable = customAttributes .FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); // 如果存在[Nullable]并且具有值为2的字节参数,则该属性为可空类型 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; } // 检查封闭类型的[NullableContext]属性 for (var type = declaringType; type != null; type = type.DeclaringType) { var context = type.CustomAttributes .FirstOrDefault(_ => _.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute"); // 如果存在[NullableContext]并且具有值为2的字节参数,则封闭类型需要可空性 if (context != null && context.ConstructorArguments.Count == 1) { return (byte)context.ConstructorArguments[0].Value! == 2; } } // 如果找不到适用的属性,则假定该属性不可空 return false; }</code>
但是,从.NET 6开始,NullabilityInfoContext API简化了可空引用类型的处理:
<code class="language-csharp">public static bool IsNullable(PropertyInfo property) => property.GetCustomAttribute<NullabilityInfoContextAttribute>() ?.DeclaredReferenceType == ReferenceType.Nullable; public static bool IsNullable(FieldInfo field) => field.GetCustomAttribute<NullabilityInfoContextAttribute>() ?.DeclaredReferenceType == ReferenceType.Nullable; public static bool IsNullable(ParameterInfo parameter) => parameter.GetCustomAttribute<NullabilityInfoContextAttribute>() ?.DeclaredReferenceType == ReferenceType.Nullable;</code>
以上是.NET 反射能否确定类属性是否使用可为 Null 的引用类型?的详细内容。更多信息请关注PHP中文网其他相关文章!