linq - 结构集合的 FirstOrDefault() 结果?

标签 linq c#-4.0 struct

所以我收集了struct (它实际上是一个 WCF 数据契约,但我认为这与这里无关)。

List<OptionalExtra> OptionalExtras;

OptionalExtrastruct .

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>'

经过一番谷歌搜索后,我意识到这是因为 OptionalExtrastruct 。我认为除非定义为可为空类型,否则它不可为空?

所以我的问题是,如果我的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/

相关文章:

c# - 导出div内容为pdf格式

C# - 使用属性名称作为字符串按属性排序的代码

c# - 如何从 LINQ 结果中删除,匹配数组中的元素

c# - 如何使用 SQL CE 加速 LINQ 插入?

go - 如何在使用 gorm 插入时跳过结构中的特定字段

C++ 结构和 volatile

struct - 为具有多个参数的矩阵实现索引运算符

c# - LINQ 包括多个 child

c# - LINQ-to-MongoDB - 仅当 2 列之间的值匹配时返回列表

c# - 使用 linq 检查 ILookup<string, string> 中的键值是否存在的最佳方法