Nullability mismatch in generic type parameter between two method arguments
我编写了以下扩展方法:
1 2 3 4 5 | // using System.Collections.Generic; internal static class TExtensions { internal static bool In< T >(this T val, HashSet< T > hs) => hs.Contains(val); } |
并尝试按如下方式使用它:
1 2 3 | var s = DateTime.Now.Hour < 15 ?"abcd" : null; var hs = new HashSet<string>(); Console.WriteLine(s.In(hs)); |
编译器在最后一行给我一个警告:
CS8620 Argument of type 'HashSet' cannot be used for parameter 'hs' of type 'HashSet' in 'bool TExtensions.In(string? val, HashSet? hs)' due to differences in the nullability of reference types.
因为编译器将
我可以通过package一个空检查来解决这个问题:
1 2 3 |
或将哈希集显式键入为具有可为空的元素:
1 |
但是有什么方法可以使用可为空的属性来允许这种情况吗?或者还有什么我可以在
1 | internal static bool In< T >([AllowNull] this T val, HashSet< T > hs) => hs.Contains(val); |
但是,正如您在问题中描述的那样,这里的实际问题是推断的泛型类型参数由
如果你可以约束到不可为空的引用类型,你可以使用这个:
1 | internal static bool In< T >(this T? val, HashSet< T > hs) where T : class => val != null && hs.Contains(val); |
对于值类型,实现将是:
1 | internal static bool In< T >(this T? val, HashSet< T > hs) where T : struct => val.HasValue && hs.Contains(val.Value); |
请注意,如果类型参数本身可以为空,则只有第一个版本(带有
您当然可以使用 null-forgiving-operator 来关闭编译器,而不是更改扩展方法: