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

C# Result模式:合并数组型Result的泛型转换问题求助

解决Result协变问题实现合并多个数组Result对象

问题核心:Result<T>是泛型类,默认不支持协变。虽然string[]实现了IEnumerable<string>,但Result<string[]>无法隐式转换为Result<IEnumerable<string>>,导致调用Flatten时出错。

下面是几种可行的解决方案:

方案一:改用协变接口(最优雅)

泛型类不能声明协变,但接口可以。把Result<T>包装成支持协变的接口,就能实现类型隐式转换:

class Result
{
    public static IResult<T> Create<T>(T value) => new ResultImpl<T>(value);
    
    public static IResult<IEnumerable<T>> Flatten<T>(params IResult<IEnumerable<T>>[] results)
    {
        return new ResultImpl<IEnumerable<T>>(results.SelectMany(x => x.Value));
    }
}

// 声明协变接口,out关键字表示T是输出类型(只读)
interface IResult<out T>
{
    T Value { get; }
}

// 原Result<T>改名为ResultImpl,实现协变接口
class ResultImpl<T> : IResult<T>
{
    internal ResultImpl(T value) => Value = value;

    public T Value { get; internal set; }
}

// 调用完全正常
var result1 = Result.Create<string[]>(["A", "B"]);
var result2 = Result.Create<string[]>(["C", "D"]);
var result3 = Result.Create<string[]>(["E", "F"]);

var result = Result.Flatten<string>(result1, result2, result3);

原理:协变接口IResult<out T>允许将派生类型的接口实例转换为基类型的接口实例,这里string[]是IEnumerable<string>的派生类型,所以IResult<string[]>可以转IResult<IEnumerable<string>>。

方案二:重载Flatten方法

如果不想改动现有Result的结构,直接给Flatten加一个数组重载:

class Result
{
    public static Result<T> Create<T>(T value) => new Result<T>(value);
    
    // 处理IEnumerable<T>的原方法
    public static Result<IEnumerable<T>> Flatten<T>(params Result<IEnumerable<T>>[] results)
    {
        return new Result<IEnumerable<T>>(results.SelectMany(x => x.Value));
    }
    
    // 新增处理T[]的重载
    public static Result<IEnumerable<T>> Flatten<T>(params Result<T[]>[] results)
    {
        return new Result<IEnumerable<T>>(results.SelectMany(x => x.Value));
    }
}

// 直接调用即可,编译器会匹配到数组重载
var result = Result.Flatten<string>(result1, result2, result3);

方案三:显式转换(临时应急)

调用时手动把每个Result<string[]>转成Result<IEnumerable<string>>,这种方式比较繁琐,适合临时场景:

var result = Result.Flatten<string>(
    Result.Create<IEnumerable<string>>(result1.Value),
    Result.Create<IEnumerable<string>>(result2.Value),
    Result.Create<IEnumerable<string>>(result3.Value)
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:40:09