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

如何通过反射无点符号访问嵌套Model属性并自动更新

反射实现嵌套属性自动Patch(无点符号访问)

现有嵌套模型定义

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public byte[] PasswordHash { get; set; } = new byte[0];
    public byte[] PasswordSalt { get; set; } = new byte[0];
    public Usertype Usertype { get; set; } = Usertype.User;
    public Details Details { get; set; }
}

public class Details
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Email { get; set; }
    public DateTime Birthdate { get; set; }
    public string Address { get; set; }
    public User User { get; set; }
}

需求说明

常规情况下我们通过点符号(如user.Details.Name)访问嵌套属性,但现在需要不使用点符号,通过反射实现以下功能:

  • 自动识别User中的嵌套类型属性(比如Details),无需手动指定类名;
  • 遍历嵌套类型的属性,将非空/有效值从User实例更新到UserDTO,实现自动Patch。

完整实现代码

针对原代码框架中的内部foreach逻辑,补充完整实现(同时处理空值、循环引用等场景):

// 用于避免循环引用(比如User和Details互相引用的情况)
var processedTypes = new HashSet<Type>();

var properties = userToUpdate.GetType().GetProperties();
foreach(var property in properties)
{
    var value = property.GetValue(userToUpdate);
    // 跳过空值或默认空字节数组(可根据实际需求调整过滤规则)
    if(value == null || (value is byte[] byteArr && byteArr.Length == 0))
        continue;

    if(property.PropertyType.IsPrimitive || property.PropertyType == typeof(string) 
       || property.PropertyType.IsEnum)
    {
        // 直接赋值基础类型属性到DTO
        typeof(UserDTO).GetProperty(property.Name)?.SetValue(userDTO, value);
    } 
    else if(!processedTypes.Contains(property.PropertyType))
    {
        processedTypes.Add(property.PropertyType);
        // 获取DTO中对应的嵌套属性
        var dtoNestedProperty = typeof(UserDTO).GetProperty(property.Name);
        if(dtoNestedProperty == null)
            continue;

        // 若DTO中的嵌套属性未实例化,先创建实例
        var dtoNestedValue = dtoNestedProperty.GetValue(userDTO);
        if(dtoNestedValue == null)
        {
            dtoNestedValue = Activator.CreateInstance(dtoNestedProperty.PropertyType);
            dtoNestedProperty.SetValue(userDTO, dtoNestedValue);
        }

        // 遍历嵌套类的所有属性
        var nestedProperties = property.PropertyType.GetProperties();
        foreach (var nestedProp in nestedProperties)
        {
            var nestedValue = nestedProp.GetValue(value);
            // 跳过空值和循环引用属性(比如Details中的User)
            if(nestedValue == null || nestedProp.PropertyType == typeof(User))
                continue;

            // 找到DTO嵌套类中对应的属性并赋值
            dtoNestedProperty.PropertyType.GetProperty(nestedProp.Name)?.SetValue(dtoNestedValue, nestedValue);
        }
    }
}

关键逻辑说明

  1. 空值过滤:提前跳过null或空字节数组,避免无效赋值操作;
  2. 类型覆盖补充:原代码仅处理基元类型和字符串,补充枚举类型判断,避免遗漏场景;
  3. 循环引用处理:用HashSet记录已处理的类型,防止User与Details互相引用导致的无限循环;
  4. DTO嵌套属性实例化:如果UserDTO中的嵌套属性(如Details)为null,通过Activator.CreateInstance创建实例后再赋值;
  5. 无点符号赋值:全程通过反射获取属性值、定位DTO对应属性,完全不使用点符号访问嵌套属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:50:21