求解价值观"Nullable value type may be null" 1.NetCore 6 中的计数



在项目定义中使用NetCore 6和<Nullable>enable</Nullable>

protected Boolean CrossBelow<T>(IList<Nullable<T>> values1, IList<Nullable<T>> values2) where T : struct, IComparable {
if (values1[values1.Count - 2] == null || values1.Last() == null || values2[values1.Count - 2] == null || values2.Last() == null)
return false;
return values1[values1.Count - 2].Value.CompareTo(values2[values2.Count - 2].Value) > 0 && values1.Last().Value.CompareTo(values2.Last().Value) < 0;
} 

但我收到了警告:

Nullable value type may be null

在一些地方,如:

values1[values1.Count - 2]

我可以使用解决部分问题

values1?[values1.Count - 2]

但是我得到了编译错误

`cannot convert from 'int?' to 'int'` 

在值上尝试相同操作时1.计数:

values1?[values1?.Count - 2]

如何解决这个问题?

values1[values1.Count - 2]

values1.Last();

基本上是函数调用,编译器不能确定它们在后续调用中产生相同的值(比如说,第一次调用Last()时,它可能不会返回null,但第二次返回null时,编译器不知道在您的情况下这是不可能的(。只要引入变量,即使没有这些警告也不会造成伤害:

protected Boolean CrossBelow<T>(IList<Nullable<T>> values1, IList<Nullable<T>> values2) where T : struct, IComparable
{
var v1Prev = values1[values1.Count - 2];
var v1Last = values1.Last();
var v2Prev = values2[values2.Count - 2];
var v2Last = values2.Last();
if (v1Prev == null || v1Last == null || v2Prev == null || v2Last == null)
return false;
return v1Prev.Value.CompareTo(v2Prev.Value) > 0 && v1Last.Value.CompareTo(v2Last.Value) < 0;
}

问题是您正在直接访问Nullable<T>Value属性。编译器不知道列表中最后一个和倒数第二个索引的值是否会在null检查和在return语句中访问这些元素之间发生变化。

这里最简单的解决方案是使用null条件运算符?.。这将允许您甚至删除显式的空检查,因为现在一切都是一次性完成的:

protected bool CrossBelow<T>(IList<T?> values1, IList<T?> values2) where T : struct, IComparable =>
values1[^2]?.CompareTo(values2[^2]) > 0
&& values1[^1]?.CompareTo(values2[^1]) < 0;

我还使用索引简化了您的数组访问。

那么上面的代码中发生了什么

您的方法采用两个IListsvalues1values2,它们包含T?的值(与Nullable<T>相同,只是更短(。请注意,IList实例本身不能为null(或者至少我们不希望它们为null(。因此,在列表本身之后,我们不需要任何null条件。因此不需要values1?[values1.Count - 2]values1之后的?。收到警告的原因是索引操作返回的元素可能为null。因此,我们在之后应用?运算符,索引我们想要的元素。

由于?.运算符,现在只有在上一次索引操作返回的值不为null的情况下,才继续执行CompareTo()语句。由于CompareTo(object? obj)无论如何都取一个可为null的值,因此我们不需要对comparand进行null检查。如果values1[^2](访问倒数第二个元素(返回的值为null,则不会对CompareTo()进行求值,并且null > 0将始终对int?求值为false。这就是为什么我们不需要在if语句中进行显式的null检查。

第二行的作用完全相同。注意,intnull的任何比较都将返回false。因此null < 0为假。

相关内容

  • 没有找到相关文章

最新更新