You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断基于引用类型的泛型参数是否可为空?

如何通过反射判断引用类型泛型参数的可空性(C# 11/.NET 7)

在启用Nullable特性的项目中,值类型泛型参数的可空性(如List<long?>)可以通过Nullable.GetUnderlyingType或NullabilityInfoContext轻松判断,但引用类型作为泛型参数的可空性(如List<String?>中的String?)无法直接通过常规反射API获取。以下是无需自定义属性的解决方案:

核心方案:递归解析泛型类型的可空元数据

利用NullabilityInfoContext结合递归遍历,获取泛型参数的可空状态。该API会读取编译器生成的可空性元数据,支持嵌套泛型类型的解析。

实现工具类

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;

public static class NullabilityReflectionHelper
{
    /// <summary>
    /// 递归获取泛型类型所有参数的可空状态
    /// </summary>
    /// <param name="genericType">泛型类型(如List<String?>)</param>
    /// <returns>每个泛型参数的可空状态,按层级顺序返回</returns>
    public static IEnumerable<NullabilityState> GetGenericParameterNullabilities(Type genericType)
    {
        if (!genericType.IsGenericType)
            yield break;

        var nullabilityContext = new NullabilityInfoContext();
        var typeNullabilityInfo = nullabilityContext.Create(genericType);

        foreach (var paramNullability in typeNullabilityInfo.GenericTypeArguments)
        {
            // 返回当前泛型参数的可空状态
            yield return paramNullability.ReadState;

            // 递归处理嵌套的泛型类型(如List<List<String?>?>中的内层List<String?>)
            foreach (var nestedState in GetGenericParameterNullabilities(paramNullability.Type))
            {
                yield return nestedState;
            }
        }
    }
}

验证示例场景

针对你提供的ReflectMe类,以下是调用示例:

// 获取Names0属性的类型(List<String?>)
PropertyInfo names0Prop = typeof(ReflectMe).GetProperty(nameof(ReflectMe.Names0))!;
Type names0Type = names0Prop.PropertyType;

// 获取泛型参数的可空状态
List<NullabilityState> names0Nullabilities = NullabilityReflectionHelper
    .GetGenericParameterNullabilities(names0Type)
    .ToList();
// names0Nullabilities[0] = NullabilityState.Nullable,对应String?的可空性

// 处理嵌套泛型的Names1属性(List<List<String?>?>?)
PropertyInfo names1Prop = typeof(ReflectMe).GetProperty(nameof(ReflectMe.Names1))!;
Type names1Type = names1Prop.PropertyType;

List<NullabilityState> names1Nullabilities = NullabilityReflectionHelper
    .GetGenericParameterNullabilities(names1Type)
    .ToList();
// names1Nullabilities[0] = NullabilityState.Nullable(对应外层List的泛型参数List<String?>?)
// names1Nullabilities[1] = NullabilityState.Nullable(对应内层List的泛型参数String?)

关键注意事项

  • 必须启用Nullable特性:确保项目文件中包含<Nullable>enable</Nullable>,否则编译器不会生成可空性元数据,反射无法获取对应信息。
  • 处理未知状态:若类型来自未启用Nullable的程序集,NullabilityState会返回Unknown,需在代码中做相应判断。
  • 区分成员本身与泛型参数的可空性:NullabilityInfoContext.Create()也可直接获取属性本身的可空状态(如Ids1是List<long?>?,属性自身可空),而上述工具类专注于泛型参数的可空性。

内容的提问来源于stack exchange,提问作者Tomcat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 03:02:36