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

C#如何实现带多泛型参数的并行查询方法并返回多类型结果集合

核心实现思路

C# 的 List<T> 确实只支持单个泛型参数,无法直接承载多类型结果,针对你的场景有两种成熟的实现方案:


方案1:固定泛型参数重载(推荐)

你提到最多同时查询3-4个表,这种方案实现成本最低且完全类型安全,利用C#的值元组承载多类型返回结果,只需要写2/3/4个参数的重载即可适配需求。

同步实现示例

// 2个查询的重载
public (List<T1> Result1, List<T2> Result2) Query<T1, T2>(params QueryModel[] queries)
    where T1 : BaseClass
    where T2 : BaseClass
{
    if (queries.Length != 2)
        throw new ArgumentException("查询数量需与泛型参数数量一致");
    
    var results = new object[2];
    // 并行执行查询
    Parallel.For(0, 2, i =>
    {
        // 这里复用你原有单查询的获取数据逻辑
        var rawData = GetRawDataFromQuery(queries[i]);
        var targetType = i == 0 ? typeof(T1) : typeof(T2);
        results[i] = JsonSerializer.Deserialize(rawData, typeof(List<>).MakeGenericType(targetType));
    });
    return ((List<T1>)results[0], (List<T2>)results[1]);
}

// 3个查询的重载
public (List<T1> Result1, List<T2> Result2, List<T3> Result3) Query<T1, T2, T3>(params QueryModel[] queries)
    where T1 : BaseClass
    where T2 : BaseClass
    where T3 : BaseClass
{
    if (queries.Length != 3)
        throw new ArgumentException("查询数量需与泛型参数数量一致");
    
    var results = new object[3];
    Parallel.For(0, 3, i =>
    {
        var rawData = GetRawDataFromQuery(queries[i]);
        var targetType = i switch
        {
            0 => typeof(T1),
            1 => typeof(T2),
            2 => typeof(T3),
            _ => throw new IndexOutOfRangeException()
        };
        results[i] = JsonSerializer.Deserialize(rawData, typeof(List<>).MakeGenericType(targetType));
    });
    return ((List<T1>)results[0], (List<T2>)results[1], (List<T3>)results[2]);
}

// 4个查询的重载按照上述逻辑扩展即可

IO密集型场景异步优化示例

如果你的查询是数据库/接口等IO密集型操作,更推荐用异步并行实现,性能更高:

public async Task<(List<T1> Result1, List<T2> Result2, List<T3> Result3)> QueryAsync<T1, T2, T3>(params QueryModel[] queries)
    where T1 : BaseClass
    where T2 : BaseClass
    where T3 : BaseClass
{
    if (queries.Length != 3)
        throw new ArgumentException("查询数量需与泛型参数数量一致");
    
    // 并行发起所有异步查询
    var dataTasks = queries.Select(q => GetRawDataFromQueryAsync(q)).ToList();
    var rawDataResults = await Task.WhenAll(dataTasks);
    
    // 按顺序反序列化对应类型
    var res1 = JsonSerializer.Deserialize<List<T1>>(rawDataResults[0]);
    var res2 = JsonSerializer.Deserialize<List<T2>>(rawDataResults[1]);
    var res3 = JsonSerializer.Deserialize<List<T3>>(rawDataResults[2]);
    
    return (res1, res2, res3);
}

调用方式

完全类型安全,编译期即可校验类型匹配:

// 调用3参数重载,直接拿到对应类型的结果
var (userList, orderList, logList) = Query<UserDto, OrderDto, LogDto>(userQuery, orderQuery, logQuery);

该方案优势是调用端不需要手动转型,代码简洁易维护,完全适配你的现有需求。


方案2:可变数量泛型查询

如果需要支持任意数量的并行查询,可以采用查询绑定返回类型的方案实现:

实现示例

public List<object> QueryMany(params (QueryModel Query, Type ReturnType)[] queryConfigs)
{
    var results = new List<object>(queryConfigs.Length);
    Parallel.ForEach(queryConfigs, config =>
    {
        var rawData = GetRawDataFromQuery(config.Query);
        var result = JsonSerializer.Deserialize(rawData, typeof(List<>).MakeGenericType(config.ReturnType));
        lock(results) results.Add(result);
    });
    return results;
}

调用方式

var results = QueryMany(
    (userQuery, typeof(UserDto)),
    (orderQuery, typeof(OrderDto)),
    (logQuery, typeof(LogDto)),
    (otherQuery, typeof(OtherDto))
);
// 手动转型使用
var userList = (List<UserDto>)results[0];
var orderList = (List<OrderDto>)results[1];

该方案灵活性更高,支持任意数量的并行查询,但调用端需要手动做类型转换,丢失了编译期类型安全校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:06:01