为什么引用和值类型的集合之间的Enumerable Min或Max不一致?

Jaa*_*rus 5 .net c# linq

在处理序列时,我很惊讶地发现minmax的行为是不同的,具体取决于源集合元素是值类型还是引用类型:

var refCollection = new object[0];
var valCollection = new int[0];
var nullableCollection = new int?[0];

var refMin = refCollection.Min(x => x); // null
var valMin = valCollection.Min(); // InvalidOperationException
var nullableMin = nullableCollection.Min(); // null
Run Code Online (Sandbox Code Playgroud)

Enumerable扩展的.NET Core实现中很好地看到了这种行为差异.

然而,当看到Jon Skeet的MinBy扩展时,情况就不是这样了,例如,正如我所预期的那样抛出任何一种情况.

行为上的差异不会导致混淆吗?返回nullref类型集合有什么好处吗?

Jon*_*eet 8

值得注意的是,可空类型(可空值类型和引用类型)在一般情况下与非可空值类型的行为不同Min:null一般来说,值被视为"缺失",因此结果并非不合理"缺失值的最小值"是"缺失值".

例如:

int?[] nullableInts = new int?[5]; // All values null
int? min = nullableInts.Min(); // No exception, min is null
nullableInts[3] = 2;
min = nullableInts.Min(); // No exception, min is 2
Run Code Online (Sandbox Code Playgroud)

对于不可为空的值类型,实际上没有指示"缺失值"的选项(除非返回类型被更改为永远是可空类型),因此例外......但是这很容易被发现对于不可为空的值类型,唯一没有最小值的情况是源为空时.

(它可能MinBy实际上应该以相同的方式表现:)

这也与LINQ to XML中的转换一致:

XElement element = null;
int? x = (int?) element; // null
int y = (int) element; // Bang
Run Code Online (Sandbox Code Playgroud)

基本上,它确实有一定的意义 - 没有选择与一切都是一致的.

  • 我想补充一点,`Min()`的功能与SQL`MIN()`的功能是一致的......空集的`MIN()`是'NULL`.显然,不可为空的值类型不能包含"NULL".所以例外. (3认同)