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

CQRS架构下C#如何实现Handle方法多类型泛型Response返回?

C# CQRS中实现多类型返回的方案

问题场景

我用C#开发CQRS架构系统,现有一段Handle方法代码:

public async Task<Response<SaleProducts>> Handle(CreateSaleProductCommand request, CancellationToken cancellationToken)
{
    var newEntity = MyCustomerMapper.Mapper.Map<SaleProducts>(request);
    if (newEntity is null)
        throw new ApplicationException("There is a problem in mapper");

    var itemToReturn = await _repositoryCommand.AddProductToSaleAsync(newEntity);
    if(itemToReturn != null)
    {
        itemToReturn.Product = await _productQueryRepository.GetByIdAsync(itemToReturn.ProductId);  
        return new Response<SaleProducts>(itemToReturn);
    }
    else
        throw new ApplicationException("There is a problem when saving the product");
}

这个方法最终返回Response<SaleProducts>类型。现在想给_repositoryCommand.AddProductToSaleAsync加验证逻辑:验证通过返回SaleProducts,不通过返回bool或string这类类型,想知道能不能实现类似public async Task<Response<SaleProducts | bool>> Handle(...)这种多类型返回的写法。

可行实现方案

C#没法直接在泛型参数里用SaleProducts | bool这种联合类型语法(C# 12虽然引入联合类型,但只能先声明类型再用,不能直接嵌在泛型里),但可以通过下面几种方式实现需求:

1. 自定义结果类

自己写个统一的结果类,把成功数据、失败状态/消息都包进去:

public class OperationResult<T>
{
    public bool IsSuccess { get; set; }
    public T? SuccessData { get; set; }
    public string? ErrorMessage { get; set; }

    // 静态方法方便创建实例
    public static OperationResult<T> Success(T data) => new() { IsSuccess = true, SuccessData = data };
    public static OperationResult<T> Failure(string message) => new() { IsSuccess = false, ErrorMessage = message };
}

然后把AddProductToSaleAsync的返回类型改成Task<OperationResult<SaleProducts>>,Handle方法调整成这样:

public async Task<Response<SaleProducts>> Handle(CreateSaleProductCommand request, CancellationToken cancellationToken)
{
    var newEntity = MyCustomerMapper.Mapper.Map<SaleProducts>(request);
    if (newEntity is null)
        throw new ApplicationException("There is a problem in mapper");

    var result = await _repositoryCommand.AddProductToSaleAsync(newEntity);
    if(result.IsSuccess)
    {
        var itemToReturn = result.SuccessData!;
        itemToReturn.Product = await _productQueryRepository.GetByIdAsync(itemToReturn.ProductId);  
        return new Response<SaleProducts>(itemToReturn);
    }
    else
        throw new ApplicationException(result.ErrorMessage ?? "There is a problem when saving the product");
}

2. 用ValueTuple返回多值

如果需求简单,直接用元组返回验证状态、数据和错误消息:

// 修改AddProductToSaleAsync的返回类型
public async Task<(SaleProducts? Product, bool IsValid, string? ErrorMsg)> AddProductToSaleAsync(SaleProducts entity)
{
    // 这里写验证逻辑
    if (!IsValid(entity))
    {
        return (null, false, "具体的验证失败原因");
    }
    // 执行保存逻辑
    var savedProduct = await SaveProduct(entity);
    return (savedProduct, true, null);
}

Handle方法里处理元组:

var (product, isValid, errorMsg) = await _repositoryCommand.AddProductToSaleAsync(newEntity);
if(isValid && product != null)
{
    product.Product = await _productQueryRepository.GetByIdAsync(product.ProductId);  
    return new Response<SaleProducts>(product);
}
else
    throw new ApplicationException(errorMsg ?? "There is a problem when saving the product");

3. C# 12联合类型(先声明再用)

C# 12支持声明联合类型,先定义一个包含允许返回类型的联合,再用在方法里:

// 定义联合类型
type SaleResult = SaleProducts | string;

// 修改AddProductToSaleAsync返回类型
public async Task<SaleResult> AddProductToSaleAsync(SaleProducts entity)
{
    if (!IsValid(entity))
    {
        return "验证不通过的具体原因";
    }
    return await SaveProduct(entity);
}

Handle方法里用模式匹配判断返回类型:

var result = await _repositoryCommand.AddProductToSaleAsync(newEntity);
if (result is SaleProducts product)
{
    product.Product = await _productQueryRepository.GetByIdAsync(product.ProductId);  
    return new Response<SaleProducts>(product);
}
else if (result is string errorMsg)
{
    throw new ApplicationException(errorMsg);
}
else
{
    throw new ApplicationException("Unexpected result type");
}

4. 用第三方联合类型库

还有专门处理联合类型的第三方库,比如OneOf,它封装了联合类型的逻辑,能让代码更简洁,返回类型可以直接写成OneOf<SaleProducts, string>,然后通过库提供的方法匹配不同结果处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:55:46