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

.NET获取自定义值类型可选参数默认值返回null问题咨询

自定义值类型可选参数默认值获取问题解析

这是不是.NET的bug?

不是,这是CLR反射API的设计行为。

当你为值类型可选参数指定default作为默认值时,CLR会将其解析为该值类型的零初始化状态(所有字段设为对应类型的默认值,比如Bar的Value字段为null)。但通过ParameterInfo.DefaultValue或RawDefaultValue获取时,会返回null——这是反射API的特殊标记,用来表示“该参数的默认值是其类型的CLR默认值”,而非实际的装箱后值类型实例。

需要注意的是:你定义的Bar结构体显式实现了无参构造函数,这会生成一个自定义实例(Value为"default constructor"),但可选参数的default和显式构造函数无关,它始终对应CLR自动生成的零初始化状态。

如何正确获取默认值?

你的代码思路是正确的,paramInfo.HasDefaultValue && paramInfo.ParameterType.IsValueType && paramInfo.DefaultValue == null这个判断逻辑可以覆盖所有需要手动生成类型默认值的场景:

  • 当参数是值类型、标记了有默认值但反射返回null时,说明需要获取该类型的CLR零初始化实例;
  • 其他场景(引用类型、值类型但反射能返回具体值,比如int的0)直接返回DefaultValue即可。

优化后的实现代码如下:

public static object? GetDefaultParameterValue(ParameterInfo paramInfo)
{
    if (!paramInfo.HasDefaultValue)
    {
        return GetDefaultValueOfType(paramInfo.ParameterType);
    }

    var defaultValue = paramInfo.DefaultValue;
    // 值类型但反射返回null,说明是CLR默认零初始化状态
    if (paramInfo.ParameterType.IsValueType && defaultValue == null)
    {
        return GetDefaultValueOfType(paramInfo.ParameterType);
    }

    return defaultValue;
}

public static object? GetDefaultValueOfType(Type type)
{
    if (!type.IsValueType)
        return null;
    
    return typeof(DefaultValueGenerator)
        .GetMethod(nameof(DefaultValueGenerator.GetDefault))
        .MakeGenericMethod(type)
        .Invoke(null, null);
}

private static class DefaultValueGenerator
{
    public static T GetDefault<T>() => default;
}

调用这个方法获取barVal的默认值时,会得到Bar的零初始化实例,调用其ToString()方法会输出你预期的Bar [value is null]。

另外需要注意:Activator.CreateInstance(typeof(Bar))会调用结构体的显式无参构造函数,得到的是自定义初始化的实例,和可选参数default对应的CLR零初始化状态完全不同,因此不适用此场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:25:11