.NET 7.0 运行时如何判断泛型参数是否可为空?
运行时判断泛型参数是否可为空的解决方案
你的问题出在NullabilityInfoContext读取的是编译时属性的可空注解,但泛型类Item<T>中Value属性的可空性由泛型参数T的实际实例化类型决定,而非属性本身的固定注解。要解决这个问题,需要直接获取泛型参数的实际类型,并针对性判断其可空性。
修正后的代码
using System.Reflection; using System.Runtime.CompilerServices; namespace ConsoleApp; public class Item<T> { public required T Value { get; init; } public bool IsNullable() { var currentType = this.GetType(); // 获取泛型参数的实际类型 var genericArgument = currentType.GetGenericArguments()[0]; // 处理值类型的可空(如 int?) if (genericArgument.IsValueType) { return genericArgument.IsGenericType && genericArgument.GetGenericTypeDefinition() == typeof(Nullable<>); } // 处理引用类型的可空(如 string?) var nullableAttr = genericArgument.CustomAttributes .FirstOrDefault(attr => attr.AttributeType == typeof(NullableAttribute)); if (nullableAttr != null) { var flags = (byte?)nullableAttr.ConstructorArguments.FirstOrDefault().Value; // flags=2 表示该引用类型被标记为可空(nullable reference type) return flags == 2; } // 默认非可空引用类型 return false; } } internal class Program { static void Main() { var nullableString = new Item<string?>() { Value = null }; var nonNullableString = new Item<string>() { Value = "" }; var nullableInt = new Item<int?>() { Value = null }; var nonNullableInt = new Item<int>() { Value = 1 }; Console.WriteLine($"nullable string is nullable: {nullableString.IsNullable()}"); Console.WriteLine($"non-nullable string is nullable: {nonNullableString.IsNullable()}"); Console.WriteLine($"nullable int is nullable: {nullableInt.IsNullable()}"); Console.WriteLine($"non-nullable int is nullable: {nonNullableInt.IsNullable()}"); // 输出: // nullable string is nullable: True // non-nullable string is nullable: False // nullable int is nullable: True // non-nullable int is nullable: False } }
关键逻辑说明
- 值类型可空判断:直接检查类型是否是
Nullable<>的泛型实例,这是值类型可空(如int?)在运行时的实际类型表现。 - 引用类型可空判断:引用类型的可空修饰符(如
string?)在运行时通过NullableAttribute标记,当该属性的构造参数flags为2时,表示该引用类型被标记为可空。
内容的提问来源于stack exchange,提问作者ctron
相关产品推荐
相关产品推荐

