& # 39; ? & # 39;在LINQ语句中间
本文关键字:中间 语句 LINQ | 更新日期: 2023-09-27 18:02:23
我可以在浏览一些不那么旧的代码时越过这条线,我不明白为什么有人会这样做:
return dbStudents.MethodToReturnAllStudents()?.Select(x => new dtoStudent(x));
MethodToReturnAllStudents
返回一个IEnumerable<SQLDomain.Student>
(dtoStudent
)在一个不同的命名空间中——所有的SQLDomain.Student
都是从一个IDataRecord
映射过来的。
为什么在这个语句的中间会有一个?
。如果MethodToReturnAllStudents
返回null
, LINQ Select
会尝试做任何事情吗?
这是到处都是可怕的代码吗?
旁注:无论哪种方式,我都在重构它以遵循一些可选的标准,并使其更具可读性。
这不是"旧代码",因为这是c# 6的一个特性,空条件运算符。当使用时,在允许在该实例上使用属性/方法之前,它会检查前面的值是否为null。如果为null,则返回null。
在此场景中,您可以将此代码转换为:
var students = dbStudents.MethodToReturnAllStudents();
if (students == null) return null;
return students.Select(x => new dtoStudent(x));
然而,这段代码实际上有一个比不熟悉的操作符更大的潜在问题。
一般的共识是IEnumerable<T>
不应该返回null,因此,不应该检查null。它应该总是返回一个含水或空的序列。
也就是说,如果这实际上是List<T>
(或null IEnumerable,尽管不太常见),这可能是一个真实的场景(尽管我仍然主张永远不要返回null,而是返回一个空列表)。
作为一个开发团队,你必须决定Null条件操作符是否更简洁和可读。就我个人而言,我是它的粉丝,只是不是在这种情况下,因为它表明了更大的设计味道。
这不是"可怕"的代码,但如果您不熟悉语法,它就不直观。我个人喜欢不那么冗长的选项。如果MethodToReturnAllStudents()返回null, LINQ将停止并返回那个null。它基本上是说
var retVal = dbstudents.MethodToReturnAllStudents();
if(retVal == null) {
return retVal;
} else {
return retVal.Select(x => new dtoStudent(x));
}
现在,正如用户所指出的,它不应该返回null,因为调用者期望一个IEnumerable。
var retVal = dbstudents.MethodToReturnAllStudents();
if(retVal == null) {
return new List<student>();
} else {
return retVal.Select(x => new dtoStudent(x));
}
使用null合并操作符使代码更加简洁,并且仍然可以正确处理返回类型,因此它不会返回null:
return dbStudents.MethodToReturnAllStudents()?.Select(x => new dtoStudent(x)) ?? new List<student>();
为空条件操作符MSDN文档
如果dbStudents.MethodToReturnAllStudents()为null,它将返回null而不是执行。select (x => new dtoStudent(x)),这将导致NullReferenceException