Mig*_*ura 7 c# .net-core c#-10.0
使用 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;
}
Run Code Online (Sandbox Code Playgroud)
但我收到警告:
Nullable value type may be null
Run Code Online (Sandbox Code Playgroud)
在一些地方,例如:
values1[values1.Count - 2]
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法解决部分问题:
values1?[values1.Count - 2]
Run Code Online (Sandbox Code Playgroud)
但我收到编译错误
`cannot convert from 'int?' to 'int'`
Run Code Online (Sandbox Code Playgroud)
在 value1.Count 上尝试相同的操作时:
values1?[values1?.Count - 2]
Run Code Online (Sandbox Code Playgroud)
怎么解决这个问题呢?
问题是您正在直接访问Value的属性Nullable<T>。编译器不知道列表中最后一个和倒数第二个索引处的值在 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;
Run Code Online (Sandbox Code Playgroud)
我还使用索引简化了您的数组访问。
那么上面的代码中发生了什么?
您的方法需要两个ILists values1和 ,values2其中包含值(与更短的T?相同)。Nullable<T>请注意,IList实例本身不能为空(或者至少我们不希望它们为空)。因此,我们在列表本身之后不需要任何空条件。所以?后面的values1invalues1?[values1.Count - 2]就不需要了。您收到警告的原因是索引操作返回的元素可能为空。因此,我们在对所需元素建立索引后应用该?运算符。
感谢运算符的执行,如果前一个索引操作返回的值不?.为空,则现在只会继续执行该语句。CompareTo()无论如何,由于CompareTo(object? obj)采用可为空的值,因此我们不需要对比较数进行空检查。values1[^2]如果(访问倒数第二个元素)返回的值为null,则CompareTo()不会对其求值,并且null > 0对于int?. 这就是为什么我们不需要在 if 语句中进行显式 null 检查。
第二行的作用完全相同。int请注意,与 的任何比较都null将返回false。所以null < 0是假的。
| 归档时间: |
|
| 查看次数: |
6907 次 |
| 最近记录: |