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

C#可空特性下如何避免重复检查AccessToken空引用?

问题:避免空引用检查重复或抑制警告

场景

我有一段获取访问令牌的代码:

private async Task<TokenResponse> GetTokenResponse(Credentials credentials, CancellationToken cancellationToken, string? scope = null)
{
    var tokenResponse = await _httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
    {
        RequestUri = new Uri("url that works", UriKind.Relative),
        ClientId = credentials.ClientId!,
        ClientSecret = credentials.ClientSecret,
        Scope = scope

    }, cancellationToken);

    if (tokenResponse.IsError || string.IsNullOrEmpty(tokenResponse.AccessToken))
    {
        throw new AuthenticationException($"Error fetching token: {tokenResponse.Error}");
    }

    return tokenResponse;
}

我需要通过两种方式调用该方法:

方式1

public async Task<string> GetAccessTokenAsync(Credentials credentials, CancellationToken cancellationToken)
{
    var tokenResponse = await GetTokenResponse(credentials, cancellationToken);
    return tokenResponse.AccessToken;
}

此方式会提示可能的空引用,因为tokenResponse.AccessToken可为null。

方式2

public async Task<TokenResponse> GetAccessTokenWithScope(Credentials credentials, string scope, CancellationToken cancellationToken)
{
    var tokenResponse = await GetTokenResponse(credentials, cancellationToken, scope);
    return tokenResponse;
}

我需要这种方式,因为后续需要TokenResponse的其他属性,包括AccessToken。

问题

在这两种调用方式中,尽管我已在GetTokenResponse方法中确认AccessToken不为null,但仍需重复检查空引用。由于TokenResponse不是自定义类无法设置必填字段,请问如何避免重复检查或使用!运算符抑制警告?


解决方案

1. 直接使用空值抑制运算符!

既然GetTokenResponse已经通过异常确保返回的TokenResponse中AccessToken非空,直接用!运算符明确告知编译器此处不会为空,是最简洁的解决方案:

修改方式1的代码:

public async Task<string> GetAccessTokenAsync(Credentials credentials, CancellationToken cancellationToken)
{
    var tokenResponse = await GetTokenResponse(credentials, cancellationToken);
    return tokenResponse.AccessToken!;
}

对于方式2,后续使用AccessToken时直接添加!即可:

var token = await GetAccessTokenWithScope(creds, "scope", ct);
var accessToken = token.AccessToken!;

2. 封装扩展方法统一处理

如果不想在代码中到处写!,可以给TokenResponse编写扩展方法,封装非空验证逻辑(即使底层已经检查,也能在后续逻辑变更时提供额外保障):

public static class TokenResponseExtensions
{
    public static string GetSafeAccessToken(this TokenResponse tokenResponse)
    {
        return tokenResponse.AccessToken ?? throw new InvalidOperationException("AccessToken cannot be null after successful token retrieval");
    }
}

调用示例:

// 方式1修改后
public async Task<string> GetAccessTokenAsync(Credentials credentials, CancellationToken cancellationToken)
{
    var tokenResponse = await GetTokenResponse(credentials, cancellationToken);
    return tokenResponse.GetSafeAccessToken();
}

// 方式2后续使用时
var token = await GetAccessTokenWithScope(creds, "scope", ct);
var accessToken = token.GetSafeAccessToken();

3. 使用Debug断言辅助编译器推断

通过Debug.Assert可以在Debug模式下验证AccessToken非空,同时让编译器自动推断该属性不为空,消除警告:

using System.Diagnostics;

public async Task<string> GetAccessTokenAsync(Credentials credentials, CancellationToken cancellationToken)
{
    var tokenResponse = await GetTokenResponse(credentials, cancellationToken);
    Debug.Assert(tokenResponse.AccessToken != null, "AccessToken should not be null after GetTokenResponse");
    return tokenResponse.AccessToken;
}

Debug.Assert仅在Debug模式下执行检查,Release模式会被移除,不会影响性能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:33:21