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

C#如何合并两个运行时确定的同泛型类型数据?

合并同类型对象集合属性的反射实现方案

之前的反射合并方案会直接覆盖目标对象的属性值,无法满足集合类型属性的合并需求(比如List<T>的AddRange效果)。以下是针对这类场景的实现方案,通过反射识别集合属性并执行合并操作:

核心合并方法

public static void Merge<T>(T target, T source)
{
    if (target == null || source == null)
        return;

    Type type = typeof(T);
    foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        if (!property.CanWrite)
            continue;

        var targetValue = property.GetValue(target);
        var sourceValue = property.GetValue(source);

        if (sourceValue == null)
            continue;

        // 判断属性是否为可添加的集合类型(实现ICollection<T>)
        var collectionInterface = property.PropertyType.GetInterface(typeof(ICollection<>).FullName);
        if (collectionInterface != null)
        {
            // 优先使用AddRange批量添加
            var addRangeMethod = property.PropertyType.GetMethod(
                "AddRange", 
                new[] { typeof(IEnumerable<>).MakeGenericType(collectionInterface.GetGenericArguments()[0]) }
            );
            
            if (addRangeMethod != null && targetValue != null)
            {
                addRangeMethod.Invoke(targetValue, new[] { sourceValue });
            }
            else if (targetValue != null)
            {
                // 无AddRange则逐个添加
                var addMethod = property.PropertyType.GetMethod("Add", collectionInterface.GetGenericArguments());
                if (addMethod != null)
                {
                    foreach (var item in sourceValue as IEnumerable)
                    {
                        addMethod.Invoke(targetValue, new[] { item });
                    }
                }
            }
            else
            {
                // 目标集合未初始化,直接赋值源集合
                property.SetValue(target, sourceValue);
            }
        }
        else
        {
            // 非集合属性:仅当目标值为空时覆盖,可根据需求调整逻辑
            if (targetValue == null)
            {
                property.SetValue(target, sourceValue);
            }
        }
    }
}

在请求方法中使用

public static async Task<T> Query<T>()
{
    var response = await RequestAsync<T>();
    var response2 = await RequestAsync<T>();

    // 将response2的数据合并到response中
    Merge(response, response2);

    return response;
}

注意事项

  • 确保目标对象的集合属性已初始化(如示例ItemsResponse中Items默认实例化为List<Items>),若未初始化会直接赋值源集合
  • 支持所有实现ICollection<T>的集合类型(如List<T>、HashSet<T>等),无AddRange的集合会自动逐个添加元素
  • 非集合属性的处理逻辑可按需调整,比如改为总是覆盖目标值,或根据业务规则合并

内容的提问来源于stack exchange,提问作者João Fernandes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:15:47