在日常编程中,经常遇到要在一组复杂类的集合(Collection)中做比较、取最大值或最小值。

举个最简单的例子,我们要在一个如下结构的集合中选取包含最大值的元素:

public class Class<T> where T : struct
{
public T? Value { get; set; }
}
var ints = new List<Class<int>>()
{
new Class<int>() { Value = },
new Class<int>() { Value = },
new Class<int>() { Value = },
new Class<int>() { Value = },
};

如果不使用.Net高级特性的做法通常是:

var max = new Class<int>() { Value = Int32.MinValue };
foreach (var i in ints)
{
if (i.Value != null && i.Value > max.Value)
{
max = i;
}
} return max;

这样的写法,除了烦琐无味以外,还有一个很明显的Bug,虽然在上面这个例子中暴露不出来,但是假设集合没有一个元素,或者组成如下:

var ints = new List<Class<int>>()
{
new Class<int>() { Value = null },
new Class<int>() { Value = null },
new Class<int>() { Value = null },
};

此时此刻,我们想要返回的是包含null值的元素,而上述方法则带给我们包含Int32最小值的元素,此元素并不在ints集合中!

你会想使用Linq框架的Max(),比如:

var max = ints.Max(i => i.Value);

但事实上这个方法只能返回元素的Value成员变量,也就是int?类型,所以这也不是我们想要的。

此时此刻,正确的方法可能是:

var max = ints.First(i => i.Value == ints.Max(j => j.Value));

但,这还是有机会抛异常的,假设集合如下

var ints = new List<Class<int>>()
{
new Class<int>() { Value = null },
new Class<int>() { Value = null },
new Class<int>() { Value = null },
null
};

在这个集合里我们加了一个真正的null元素(而非包含null值的元素),ints.Max()就会抛NullReferenceException。

为了解决这个问题,我们可以将max声明改写为:

var max = ints.First(i => i.Value == ints.Max(j => { return j == null ? null : j.Value; }));

你可能已经注意到了,Max()方法中加了null值判断,但First()方法中却不需要。请先不要急于抱怨微软设计的集合方法有行为不一致的现象。

至于为什么,我将这个作业交给你,先自己在下面这个链接里挖掘一下答案吧。:)

http://referencesource.microsoft.com/

(此网站是微软早在两年前建设好的用于方便软件工程师查看.Net源代码的网站)

在含有null值的复杂类的集合(Collection)中取最大值的更多相关文章

  1. 【SQL】含有NULL值的排序

    查询结果中有NULL值,当进行升序排序时,NULL值默认为“最大值”,排在最后面.要想改变NULL值的显示顺序,只需要在SQL语句后面加上NULLS FIRST(排在前面),NULLS LAST(排在 ...

  2. 问题:oracle 排序 null值放在最后;结果: ORACLE中null的排序问题

    ORACLE中null的排序问题 关键字: oracle nulls 问题描述:    在平时的业务处理中,经常遇到要对业务数据进行排序,并且要对null值也做相应的排序.在Oracle中,进行Ord ...

  3. 数据库 SQL :有关 NULL 值引发 TRUE、FALSE、UNKNOW 三值逻辑

    在 Java.C# 中,相信如果是 boolean 类型值,只有两种选择 true.false.然而,在 SQL 查询中,NULL 值的引入,使得新增了 UNKNOW ,因此,就产生了 TRUE.FA ...

  4. sql 中的null值

    1.包含null的表达式都为空 select salary*12+nvl(bonus,0) nvl是虑空函数 2. null值永远!=null select  * from emp  where bo ...

  5. 关于数据库NULL值的几个问题思考

    最近在写项目,拼接SQL时,发现好多关于NULL值的问题,现在把这些问题整理出来,以供日后参考. 对于Oracle数据库: 一.排序 Oracle对于null值的排序,有一个函数可以进行操作: 在默认 ...

  6. MySQL索引对NULL值的处理

    # 索引不会包含有NULL值的列 只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的.所以我们在数据库设计时不要让字段的默认值为NU ...

  7. 源码分析springboot自定义jackson序列化,默认null值个性化处理返回值

    最近项目要实现一种需求,对于后端返回给前端的json格式的一种规范,不允许缺少字段和字段值都为null,所以琢磨了一下如何进行将springboot的Jackson序列化自定义一下,先看看如何实现,再 ...

  8. 奇妙的NULL值,你知道多少

    <NULL值的多义性分析> 谈到NULL值,很多人都是很熟悉,但是深入了解后,又感觉到陌生,对其含义和用法,都无法很准确的理解.NULL在数据库和编程语言中,存在的意义和附带的含义不同. ...

  9. 不再迷惑,无值和NULL值的转换

    在关系型数据库的世界中,无值和NULL值的区别是什么?一直被这个问题困扰着,甚至在写TSQL脚本时,心有戚戚焉,害怕因为自己的一知半解,挖了坑,贻害后来人,于是,本着上下求索,不达通幽不罢休的决心(开 ...

随机推荐

  1. Android RelativeLayout

    RelativeLayout为相对布局,这种布局内的组件总是相对兄弟组件.父容器来确定的,在定义控件的位置时,需要参照其他控件的位置. 这个程序实现了一个梅花的相对布局 <?xml versio ...

  2. Objective-c Category(类别)

    NSStringUtilities.h: #import <Foundation/Foundation.h> @interface NSString(Utilities) -(BOOL) ...

  3. 在电脑上装ubuntu12.04系统,内核文件是那个?

    在电脑上装ubuntu12.04系统,我们能看到的是根文件系统,那么内核文件(zlmage)是那个? ???

  4. 【HDOJ】3660 Alice and Bob's Trip

    就是一个基本的dfs.可关键问题是c/c++/g++光输入就超时了.还是写java过的,毕竟时限4s.都放弃希望了,没想到还真过了. import java.lang.*; import java.i ...

  5. [Hadoop源码解读](二)MapReduce篇之Mapper类

    前面在讲InputFormat的时候,讲到了Mapper类是如何利用RecordReader来读取InputSplit中的K-V对的. 这一篇里,开始对Mapper.class的子类进行解读. 先回忆 ...

  6. c#集合类的线程安全

    即位于System.Collections命名空间下的集合,如Hashtable,ArrayList,Stack,Queue等.其均提供了线程同步的一个实现 集合线程同步的问题 public clas ...

  7. From delegates to lambdas z

    I thought of naming this post “Evolution of lambdas in C#”, then I decided that wouldn’t be closest ...

  8. Apk修改利器:ApkToolkit v2.1

    作 者: Mzucore 时 间: 2013-05-10, 17:18:23 链 接: http://www.unpack.cn/thread-93058-1-1.html 下载地址:http://b ...

  9. [转]NHibernate之旅(12):初探延迟加载机制

    本节内容 引入 延迟加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过前面文章的分析,我们知道了如何使用NHibernate,比如CRUD操作.事务.一对多.多对多映射等问题,这 ...

  10. mysql 一个较特殊的问题:You can't specify target table for update in FROM clause

    mysql 一个较特殊的问题:You can't specify target table for update in FROM clause 即:不能先select出同一表中的某些值,再update ...