問題:
.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中文網其他相關文章!