所以我收集了struct
(它实际上是一个 WCF 数据契约,但我认为这与这里无关)。
List<OptionalExtra> OptionalExtras;
OptionalExtra
是 struct
.
public partial struct OptionalExtra
现在我正在运行以下语句:
OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra != null)
{
}
现在这无法编译:
the operator != cannot be applied to opperands of type OptionalExtra and
'<null>'
经过一番谷歌搜索后,我意识到这是因为 OptionalExtra
是 struct
。我认为除非定义为可为空类型,否则它不可为空?
所以我的问题是,如果我的where
语句不返回任何结果 FirstOrDefault
的结果是什么称呼?会抛出异常吗?
顺便说一句,这不应该发生,但安全总比后悔好。
最佳答案
如果您的集合为空,FirstOrDefault
将返回 default(OptionalExtras)
。结构体的默认值是该结构体的所有值依次默认初始化(即零、空等)。
如果您假设存在一个元素,并且您的代码不适用于空集合,使用 First()
相反,因为当您的集合为空时,这会引发异常。通常,快速失败比返回错误数据要好。
如果你不能假设会有一个元素,但也不能处理结构默认初始化,你可以将集合中的结构设置为 nullable value type ,例如如下:
OptionalExtras
.Where(w => w.Code == optExtra.Code)
.Cast<OptionalExtra?>()
.FirstOrDefault();
这样,即使对于结构体,您也可以获得 null 返回。这里的关键思想是扩展可能值的集合以包括除 OptionalExtra
之外的其他值。允许检测空列表。如果您不喜欢可空值,则可以使用 Maybe<>
实现(不是 .NET 内置),或使用空列表或单个列表(例如 .Take(1).ToArray()
。但是,可为 null 的结构可能是您的最佳选择。
TL;DR;
-
.FirstOrDefault<T>()
返回default(T)
如果序列为空 - 使用
.First()
相反,如果您假设列表非空。 - 转换为可为空,然后使用
.FirstOrDefault<T>()
当你不能假设列表非空时。
关于linq - 结构集合的 FirstOrDefault() 结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15407065/