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

C#中如何让编译器识别Result<T>已排除失败类型,直接获取成功值?

优雅处理Result的编译期类型推断问题

针对你遇到的场景,这里提供几种简洁且类型安全的实现方式,无需额外冗余判断或强制转换:

1. 扩展方法封装(推荐)

将类型判断和取值逻辑封装到扩展方法中,调用方只需一行代码完成取值或异常抛出:

public static class ResultExtensions
{
    public static T GetValueOrThrow<T>(this Result<T> result)
    {
        return result switch
        {
            ResultSuccess<T> success => success.Value,
            ResultFailure<T> failure => throw new Exception($"操作失败:{failure.ErrorMessage}"),
            _ => throw new UnreachableException("未知的Result子类,违反类型约束")
        };
    }
}

调用示例:

var result = DoSomething();
var value = result.GetValueOrThrow(); // 直接获取值,失败时自动抛出异常

2. 利用switch表达式的穷尽性检查

如果你的Result<T>基类是抽象类,且仅存在ResultSuccess<T>和ResultFailure<T>两个子类(确保无其他子类可继承,比如将基类构造函数设为internal),C#编译器会识别模式匹配的穷尽性,无需处理"其他"情况:

var result = DoSomething();
var value = result switch
{
    ResultFailure<T> failure => throw new Exception($"操作失败:{failure.ErrorMessage}"),
    ResultSuccess<T> success => success.Value
};

若编译器仍要求默认分支,可添加_ => throw new UnreachableException(),该分支永远不会执行,但能消除编译警告。

3. 优化类结构为封闭继承(C# 9+)

使用C# 9的record类型或密封类嵌套,让编译器明确知道Result<T>的所有可能子类,进一步强化类型推断:

方式A:抽象Record继承

public abstract record Result<T>;
public record ResultSuccess<T>(T Value) : Result<T>;
public record ResultFailure<T>(string ErrorMessage) : Result<T>;

方式B:密封基类+嵌套子类

public abstract class Result<T>
{
    // 私有构造函数,确保仅嵌套子类可继承
    private Result() { }

    public sealed class ResultSuccess : Result<T>
    {
        public T Value { get; }
        public ResultSuccess(T value) => Value = value;
    }

    public sealed class ResultFailure : Result<T>
    {
        public string ErrorMessage { get; }
        public ResultFailure(string errorMessage) => ErrorMessage = errorMessage;
    }
}

此时使用switch表达式或模式匹配时,编译器会自动识别穷尽性,无需额外处理分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:20:11