扩展方法中IEnumerable<T?>无法转换为IEnumerable<T>的问题排查
问题根源与解决方案
问题出在泛型类型推断的歧义上。当你调用CollectionUtils.From(parentId, (uint)b)时,编译器可能将泛型参数T推断为uint?而非uint:
- 若
T为uint?,则T?等价于uint?(C#不允许嵌套可空值类型,Nullable<Nullable<uint>>会被编译器简化为Nullable<uint>) - 此时
WhereNonNull<T>的泛型参数T也会被推断为uint?,最终返回IEnumerable<uint?>,导致boneId仍是可空类型
解决方法
1. 显式指定From方法的泛型参数
调用时明确指定T为uint,消除推断歧义:
foreach(var boneId in CollectionUtils.From<uint>(parentId, (uint)b).WhereNonNull())
2. 优化WhereNonNull方法
针对值类型可空的场景,直接使用HasValue和Value替代Cast<T>,避免不必要的装箱拆箱,同时通过泛型约束确保类型安全:
public static IEnumerable<T> WhereNonNull<T>(this IEnumerable<T?> enumerable) where T : struct { foreach (var item in enumerable) { if (item.HasValue) yield return item.Value; } }
3. 可选:为From方法添加类型约束
限制T为值类型,从根源避免T被推断为可空值类型:
public static IEnumerable<T?> From<T>(params T?[] values) where T : struct { return values.AsEnumerable(); }
内容的提问来源于stack exchange,提问作者user3001150
相关产品推荐
相关产品推荐

