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

是否存在适用于IEnumerable返回值的NotNullIfNotNullAttribute类似特性?

解决方案

针对你提出的需求——当输入参数defaultValue非null时,返回的IEnumerable<T?>中所有元素均为非null,可以通过以下方式实现:

.NET 7+ 官方解决方案

.NET 7及以上版本引入了ItemNotNullIfNotNullAttribute(位于System.Diagnostics.CodeAnalysis命名空间),专门用于标注集合/枚举类型的返回值与输入参数的nullable关联关系:

[return: ItemNotNullIfNotNull(nameof(defaultValue))]
public static IEnumerable<T?> GetValuesOrDefault<T>(T? defaultValue)
{
    return GetValuesFromSomewhere<T>().Select(x => x ?? defaultValue);
}

这个属性会告诉编译器:当defaultValue不为null时,返回的IEnumerable<T?>中的每个元素都不会是null,因此你可以安全地将其赋值给IEnumerable<string>类型的变量而不会收到警告。

旧版本.NET 兼容方案

如果你的项目基于.NET 6或更早版本,官方并未提供这个属性,但可以手动定义一个符合编译器识别规则的自定义属性,编译器同样会遵循其语义:

namespace System.Diagnostics.CodeAnalysis
{
    [AttributeUsage(AttributeTargets.ReturnValue, AllowMultiple = true)]
    public sealed class ItemNotNullIfNotNullAttribute : Attribute
    {
        public ItemNotNullIfNotNullAttribute(string parameterName)
        {
            ParameterName = parameterName;
        }

        public string ParameterName { get; }
    }
}

定义后即可像上面一样使用该属性,同样能达到消除警告的效果。

修改后的完整示例

#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.CodeAnalysis;

public class Program
{
    public static void Main()
    {
        string? s1 = GetValueOrDefault<string>(null);
        string s2 = GetValueOrDefault<string>("");   // 正常,无警告
        
        IEnumerable<string?> e1 = GetValuesOrDefault<string>(null);
        IEnumerable<string> e2 = GetValuesOrDefault<string>("");   // 现在无警告
    }
    
    [return: NotNullIfNotNull(nameof(defaultValue))]
    public static T? GetValueOrDefault<T>(T? defaultValue)
    { 
        return GetValueFromSomewhere<T>() ?? defaultValue;
    }
    
    [return: ItemNotNullIfNotNull(nameof(defaultValue))]
    public static IEnumerable<T?> GetValuesOrDefault<T>(T? defaultValue)
    {
        return GetValuesFromSomewhere<T>().Select(x => x ?? defaultValue);
    }
    
    // 示例中的占位方法
    private static T? GetValueFromSomewhere<T>() => default(T);
    private static IEnumerable<T?> GetValuesFromSomewhere<T>() => new T?[] { default(T) };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:32:09