Max*_*Max 4 c# ienumerable value-type reference-type
考虑以下:
var emptyValueList = new List<int>(); //any value type (long, float, any struct ...)
var minimum = emptyValueList.Min();
Run Code Online (Sandbox Code Playgroud)
这将抛出InvalidOperationException(Sequence不包含任何元素).
现在让我们尝试使用引用类型:
var emptyReferenceList = new List<object>(); //any ref type will do such as object ...
var minimum = emptyReferenceList.Min();
Run Code Online (Sandbox Code Playgroud)
这不会抛出并返回null.就好像default第二种情况要求操作员,而第一种情况则不然.它也适用于可空类型(例如int?,即使它们是值类型).
我想知道为什么会这样,如果背后有一个具体的推理?
这是一个设计决定,我们将不得不向BCL的作者询问.
Min扩展方法有各种重载.对于允许的类型null,我相信在搜索最小值时会Min跳过所有null值.这适用于引用类型和类型Nullable<>(在您的示例中Nullable<int>),它不是引用类型,但允许null(Min方法决定忽略).
因此,对于不可为空的结构,作者Min可能认为返回是"危险的",default(TSource)因为在其他情况下(通常是数字0),这可能是有意义的(即非空)最小值,因此输出可能被误解.
对于允许的类型null,因为作者选择跳过null从源产生的值,可以安全地假设null只有在序列除了包含null值(包括en empty source的情况)时才返回.
请注意,在IComparer<>可空类型或引用类型的标准下,该null值小于任何非空值.对于排序算法(如所使用的算法List<>.Sort),订单必须是完全的和可传递的.因此,我们得到:
Console.WriteLine(
Comparer<int?>.Default.Compare(null, 7)
); // "-1"
Console.WriteLine(
Nullable.Compare((int?)null, 7)
); // "-1"
Console.WriteLine(
new List<int?> { 9, null, 7, 13, }
.OrderBy(ni => ni).First()
); // ""
// 'Min' is special in that it disregards 'null' values
Console.WriteLine(
new List<int?> { 9, null, 7, 13, }
.Min()
); // "7"
Run Code Online (Sandbox Code Playgroud)
和Min适用于真正的参考类型相同的方式,例如System.Version(这是一种class类型):
var li = new List<Version> { new Version("9.0"), null, new Version("7.0"), new Version("13.0"), };
Console.WriteLine(li.OrderBy(ve => ve).First());
Console.WriteLine(li.Min());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
512 次 |
| 最近记录: |