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

C#中typeof调用GetProperties无返回而GetType可返回的原因及解决方法

问题原因

你遇到的问题本质是泛型参数的类型推断规则导致的:

  1. 首次调用GetPropertyKeyValue(home, null, pairs)时,泛型参数T会被推断为你传入的Home实例类型,typeof(T)取到的是正确的Home类元数据,因此可以正常获取属性列表。
  2. 递归调用时,你传入的第一个参数是property.GetValue(obj, null)的返回值,这个方法的返回值固定为object类型,因此泛型参数T会被推断为System.Object,typeof(T)实际取到的是基类Object的元数据,本身没有你定义的业务属性,自然返回空集合。

解决方案

你不需要依赖实例来获取属性元数据,上层属性已经包含了下属属性的类型定义,我们可以调整方法逻辑,显式传递要反射的类型,同时兼容实例为null的场景:

using System.Reflection;
using System.Collections.Generic;

// 对外暴露的泛型入口方法
public void GetPropertyKeyValue<T>(T obj, string prefix, List<ExtractedTerm> pairs)
{
    if (pairs == null)
    {
        throw new ArgumentNullException(nameof(pairs));
    }
    // 首次调用传入泛型对应的类型和实例
    GetPropertyKeyValueCore(typeof(T), obj, prefix, pairs);
}

// 内部核心递归方法,显式接收目标类型参数
private void GetPropertyKeyValueCore(Type targetType, object obj, string prefix, List<ExtractedTerm> pairs)
{
    // 从传入的目标类型取属性元数据,和实例是否为null无关
    var properties = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (var property in properties)
    {
        // 拼接点分路径的key
        string key = string.IsNullOrWhiteSpace(prefix) 
            ? property.Name 
            : $"{prefix}.{property.Name}";
        
        Type propertyType = property.PropertyType;
        // 实例为null时直接赋值null,避免空引用
        object value = obj == null ? null : property.GetValue(obj, null);

        // 判断是否为需要递归的自定义类类型
        if (propertyType.IsClass 
            && !propertyType.IsInterface 
            && !propertyType.IsEnum 
            && !propertyType.IsPrimitive 
            && propertyType != typeof(string))
        {
            // 递归时传入当前属性的类型,不需要依赖泛型推断
            GetPropertyKeyValueCore(propertyType, value, key, pairs);
            continue;
        }

        pairs.Add(new ExtractedTerm(key, value, propertyType));
    }
}

调用方式和你原来的写法完全一致,不需要修改调用代码。这个方案的优势:

  • 始终通过属性定义的PropertyType获取元数据,既避免了泛型推断错误,也不需要调用实例的GetType()方法,不会因为实例为null抛出空引用异常
  • 即便中间层级的实例为null(比如示例中的Street属性未赋值),也可以完整生成所有层级的点分路径key,对应值为null,符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:51:02