是否存在适用于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
相关产品推荐
相关产品推荐

