![](/img/trans.png)
[英]Why is Enumerable Min or Max inconsistent between collections of reference and value types?
[英]Bewildered by Enumerable Min and Max extension methods behavior with uninitialized nullable types
有人可以阐明(或自由推测)为什么Linq Min和Max扩展方法在处理未初始化的可空类型时会表现出它们的行为吗?
也许最简单的方法是显示我观察到的内容:
int? a = null;
int? b = 1;
Nullable.Compare(a, b); // -1, indicating null is smaller then 1
new int?[] { null, 1 }.OrderBy(x => x).First(); // null, null smaller then 1
new[] { 0, 1 }.Min(); // 0 as expected
new int[] { }.Min(); // invalidoperator exception as expected
到目前为止一切顺利,但随后...
new int?[] { null, 1 }.Max(); // 1 as expected
new int?[] { null, 1 }.Min(); // 1 ?????, why not null ?
new int?[] { null, null }.Min(); // null, why null now and not above ?
new int?[] { }.Min(); // null, and no exception ???
我承认,我一开始并不特别在意Nullable类型,但这是另一个故事:-)
我仍然对为什么以这种方式实施感到好奇。
干杯,巴特
您可以反编译Nullable源代码,从而得到以下定义:
public static int Compare<T>(Nullable<T> n1, Nullable<T> n2) where T : struct
{
if (n1.HasValue) {
if (n2.HasValue) return Comparer<T>.Default.Compare(n1.value, n2.value);
return 1;
}
if (n2.HasValue) return -1;
return 0;
}
看起来nullable.compare方法在n1为null和n2具有值的情况下有意返回-1。
同样,您可以反编译linq源代码,从而得到以下定义:
public static int? Min(this IEnumerable<int?> source) {
if (source == null) throw Error.ArgumentNull("source");
int? value = null;
foreach (int? x in source) {
if (value == null || x < value)
value = x;
}
return value;
}
源对象上的迭代检查值是否为null,如果为null,则将x分配给value *。 这只是linq的默认实现,它是在与null进行比较时返回一个数字作为最小值。
关于为什么要这样做的问题,我认为这是因为null表示缺少值而不是整数值,并且他们(编写linq的人)不同意可比方法的最初构建方式。 他们可能发现没有正常执行路径,其中空将被认为是最好的回答“什么是空值和整数的这个列表的最小值 ”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.