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

泛型子类与类型推断——这是唯一实现方式吗?

当然不是啦!你用非泛型基类+泛型子类的方式来实现成功/失败模型是完全可行的,但实际上还有不少其他方案可以达到类似的效果,甚至在某些场景下更简洁灵活。

下面给你列举几种常见的替代实现方式:

1. 泛型约束+静态工厂方法

这种方式通过一个统一的泛型结果类,配合私有构造函数和静态工厂方法来创建实例,编译器能自动根据返回值推断类型,代码也更紧凑:

public class Result<T>
{
    public bool IsSuccess { get; }
    public T? Value { get; }
    public string? ErrorMessage { get; }

    // 私有构造函数,强制通过工厂方法创建实例
    private Result(bool isSuccess, T? value, string? errorMessage)
    {
        IsSuccess = isSuccess;
        Value = value;
        ErrorMessage = errorMessage;
    }

    // 成功结果工厂方法
    public static Result<T> Success(T value) => new Result<T>(true, value, null);
    // 失败结果工厂方法
    public static Result<T> Failure(string errorMessage) => new Result<T>(false, default, errorMessage);
}

调用时直接通过静态方法生成实例,类型推断会自动生效:

var successRes = Result<int>.Success(100);
var failRes = Result<string>.Failure("参数错误");

2. 辨别联合(Discriminated Unions)

从C# 9.0开始支持的record类型+辨别联合,完全贴合函数式编程的成功/失败模型,模式匹配时格外方便,类型推断也非常友好:

// 抽象基类
public abstract record Result;
// 成功结果,携带泛型返回值
public record SuccessResult<T>(T Value) : Result;
// 失败结果,携带错误信息
public record FailureResult(string ErrorMessage) : Result;

// 使用示例
Result FetchData(bool isSuccess)
{
    return isSuccess ? new SuccessResult<int>(200) : new FailureResult("请求超时");
}

// 模式匹配处理结果
var result = FetchData(true);
if (result is SuccessResult<int> success)
{
    Console.WriteLine($"成功:{success.Value}");
}
else if (result is FailureResult fail)
{
    Console.WriteLine($"失败:{fail.ErrorMessage}");
}

3. 泛型接口+隐式转换

通过定义泛型接口,分别实现成功/失败的具体类,再添加隐式转换操作符,让调用代码更直观,编译器会自动完成类型推断:

public interface IResult<T>
{
    bool IsSuccess { get; }
    T? Value { get; }
    string? ErrorMessage { get; }
}

public class Success<T> : IResult<T>
{
    public bool IsSuccess => true;
    public T Value { get; }
    public string? ErrorMessage => null;

    public Success(T value) => Value = value;

    // 隐式转换:从泛型值直接转为Success实例
    public static implicit operator Success<T>(T value) => new Success<T>(value);
}

public class Failure<T> : IResult<T>
{
    public bool IsSuccess => false;
    public T? Value => default;
    public string ErrorMessage { get; }

    public Failure(string errorMessage) => ErrorMessage = errorMessage;

    // 隐式转换:从错误信息字符串直接转为Failure实例
    public static implicit operator Failure<T>(string errorMessage) => new Failure<T>(errorMessage);
}

调用时可以直接赋值,不需要显式声明类型:

IResult<int> res1 = 200; // 自动转为Success<int>
IResult<int> res2 = "数据库连接失败"; // 自动转为Failure<int>

这些方案各有优劣:辨别联合更符合现代函数式编程风格,静态工厂方法兼容性更好(支持旧版C#),隐式转换则让调用代码更简洁。你可以根据项目的C#版本、团队习惯以及实际需求来选择合适的实现方式~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:45:50