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

C#中如何优雅动态构建带可选参数的GET查询字符串

方案1:反射通用实现(最省心,改动最小)

直接通过反射遍历QueryClass的所有公共属性,自动过滤空值生成字典,不需要针对每个属性写硬编码逻辑:

private string BuildQuery(QueryClass query)
{
    var queryDictionary = query.GetType()
        .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
        .Where(prop => prop.GetValue(query) is string value && !string.IsNullOrEmpty(value))
        .ToDictionary(
            prop => prop.Name.ToLowerInvariant(), // 可根据需求调整参数名大小写规则
            prop => (string)prop.GetValue(query)
        );

    return new FormUrlEncodedContent(queryDictionary).ReadAsStringAsync().Result;
}

提示:如果需要支持自定义参数名(比如属性名为Offset,接口要求参数为current_offset),可以给属性加[JsonPropertyName("current_offset")]或自定义特性,反射时读取特性值作为字典的key即可。

方案2:原生封装字典(无反射开销,性能最优)

直接调整QueryClass的结构,内部封装字典,属性赋值时自动写入字典,完全避免运行时反射开销:

public class QueryClass : Dictionary<string, string>
{
    public string Offset 
    { 
        get => TryGetValue("offset", out var val) ? val : null;
        set { if (!string.IsNullOrEmpty(value)) this["offset"] = value; else Remove("offset"); }
    }

    public string Limit 
    { 
        get => TryGetValue("limit", out var val) ? val : null;
        set { if (!string.IsNullOrEmpty(value)) this["limit"] = value; else Remove("limit"); }
    }

    public string Sort 
    { 
        get => TryGetValue("sort", out var val) ? val : null;
        set { if (!string.IsNullOrEmpty(value)) this["sort"] = value; else Remove("sort"); }
    }
}

对应的BuildQuery方法可以简化到极致:

private string BuildQuery(QueryClass query)
{
    return new FormUrlEncodedContent(query).ReadAsStringAsync().Result;
}

这种方案虽然仍需要定义属性,但不需要额外维护if判断逻辑,属性赋值时自动处理空值过滤和字典写入,适合性能要求高的场景。

方案3:源生成器(兼顾性能和少写代码)

如果QueryClass属性特别多,又不想用反射也不想挨个写属性的字典逻辑,可以用C#源生成器在编译时自动生成转换逻辑,没有运行时开销,也不需要手动写硬编码。

额外优化建议

原代码中使用ReadAsStringAsync().Result属于同步等待异步方法,高并发场景下可能出现死锁,建议将BuildQuery改为异步方法:

private async Task<string> BuildQueryAsync(QueryClass query)
{
    var queryDictionary = // 上述任意方案生成的字典
    using var content = new FormUrlEncodedContent(queryDictionary);
    return await content.ReadAsStringAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:15:01