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

基于C# Record实现可区分联合:自研方案对比第三方库的不足探讨

自研C# Record可区分联合方案的疑问

背景与自研方案

为避免在应用层通过抛出异常处理预期错误,我尝试用C# Record实现可区分联合,认为引入第三方库过于冗余,因此自研了如下方案:

public abstract record CreateCustomerResponse
{
    private CreateCustomerResponse() { }

    public sealed record Success(Customer Customer) : CreateCustomerResponse;

    public sealed record Error(string Code, string Message) : CreateCustomerResponse, IErrorResponse;

    public sealed record Unauthorized() : CreateCustomerResponse;
}

方案实现与使用

该方案通过抽象密封Record限制类型范围,实现方式与第三方库的可区分联合类似:

static CreateCustomerResponse CreateCustomer(Customer customer)
{
    // Or do data validation however you prefer.
    if (string.IsNullOrEmpty(customer.FirstName))
        return new CreateCustomerResponse.Error(nameof(customer.FirstName), "First name is required");

    if (string.IsNullOrEmpty(customer.LastName))
        return new CreateCustomerResponse.Error(nameof(customer.LastName), "Last name is required");

    return new CreateCustomerResponse.Success(customer);
}

且可借助C#模式匹配轻松消费:

static string PrintResponse(CreateCustomerResponse response)
{
    return response switch
    {
        CreateCustomerResponse.Success result => $"OK, so {result.Customer.FirstName} was created",
        CreateCustomerResponse.Error => $"Sorry, operation failed: {response}",
        CreateCustomerResponse.Unauthorized => "You're unauthorized pal",
        _ => throw new NotImplementedException()
    };
}

目前发现仅存在switch表达式无法识别全案例覆盖的小问题,但添加默认分支即可解决。我看到很多人使用OneOf等第三方库实现类似功能,想请教:该自研方案是否存在未考虑到的缺陷?相比第三方库是否遗漏了关键特性?


解答

你的自研方案在简单业务场景下可以正常运行,但对比OneOf这类成熟第三方库,确实存在不少未考虑到的缺陷和特性遗漏:

  • 重复代码冗余:每个业务操作都要编写一套独立的抽象Record+密封子类(比如CreateOrderResponse、UpdateCustomerResponse),大量重复结构会显著增加维护成本;而OneOf通过泛型可直接定义OneOf<Success<Customer>, Error, Unauthorized>,无需重复编写类结构。
  • 通用操作缺失:第三方库通常提供了通用的映射、匹配、链式处理方法,比如OneOf的Match方法可直接链式调用处理结果,还支持Bind、Map等操作组合业务逻辑;自研方案每次都要手动编写switch表达式,无法复用通用逻辑,代码复用性差。
  • 编译期全分支覆盖检查缺失:你遇到的switch无法识别全案例覆盖是核心问题——OneOf配合C# Nullable参考类型和静态分析工具,可在编译期强制检查所有分支是否被处理,避免遗漏新的结果类型;而自研方案只能依赖手动添加默认分支,编译期无法保障,后续新增分支时容易出现遗漏。
  • 序列化兼容性问题:成熟第三方库已经处理了JSON序列化/反序列化的兼容性,能正确识别不同分支类型并完成序列化;自研方案如果需要跨服务传输结果,可能需要手动编写JsonConverter,否则序列化后无法正确反序列化为对应的子类,增加额外开发成本。
  • 扩展性不足:如果后续需要给所有结果添加通用属性(比如请求ID、处理时间戳),自研方案需要修改每个抽象Record类;而第三方库可通过泛型扩展或统一基类批量处理,扩展性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:15:38