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

如何强制泛型方法绝不返回Null值(含异步场景)

问题场景

在以下代码示例中:

async Task Main()
{
    // 实际上data永远不可能为null,但这里被推断为Response?类型
    var data1 = GetResponseData();
    var data2 = await GetResponseDataAsync();
}

private Response GetResponseData()
{
    var data = MyHelper("the method", m => GetData<Response>(m));
    return data;
}
private Task<Response> GetResponseDataAsync()
{
    var data = MyHelperAsync("the method", m => GetDataAsync<Response>(m));
    // 这里会触发可空性警告
    return data;
}
class Response
{
    public int prop { get; set; }
}

TResp? GetData<TResp>(string method)
{
    return default(TResp);
}

TResp MyHelper<TResp>(string method, Func<string, TResp> getData)
{
    var data = getData(method);
    if (data is null)
        throw new Exception("data should not be null");
        
    return data;
}

Main方法中的data变量被编译器标记为可空类型(Response?),但实际上它永远不会为null。需要让编译器识别这一事实,且不能修改可能返回null的GetData方法。

解决方案

同步场景修正

给MyHelper方法添加[return: System.Diagnostics.CodeAnalysis.NotNull]特性,明确告知编译器该方法返回值绝不会为null,无需修改GetData方法:

using System.Diagnostics.CodeAnalysis;

// 其余代码保持不变

[return: NotNull]
TResp MyHelper<TResp>(string method, Func<string, TResp> getData)
{
    var data = getData(method);
    if (data is null)
        throw new Exception("data should not be null");
        
    return data;
}

添加该特性后,编译器会正确推断GetResponseData()的返回值为非空Response,Main中的data1也会被识别为非空类型,不再出现错误的可空标记。

异步场景解决方案

该方案同样适配异步场景,只需给异步版的MyHelperAsync添加[return: NotNull]特性即可:

async Task Main()
{
    var data2 = await MyHelperAsync("the method", m => GetDataAsync<Response>(m));
    
    data2.prop.Dump();
}

class Response
{
    public int prop { get; set; }
}

Task<TResp?> GetDataAsync<TResp>(string method)
{
    return Task.FromResult(default(TResp));
}

using System.Diagnostics.CodeAnalysis;

[return: NotNull]
async Task<TResp> MyHelperAsync<TResp>(string method, Func<string, Task<TResp>> getData)
{
    var data = await getData(method);
    if (data is null)
        throw new Exception("data should not be null");

    return data;
}

添加特性后,MyHelperAsync的返回值会被编译器识别为非空的Task<Response>,异步场景下的可空性警告会自动消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:36:04