在日常编程中,经常遇到要在一组复杂类的集合(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. Document字段发生变化后,报的错

    2016-10-11 15:27:47,828 [ERROR] [main] SpringApplication:838 - Application startup failedorg.springf ...

  2. GC回收建议

    1.最基本的建议就是尽早释放无用对象的引用.大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为 null.我们在使用这种方式时候,必须特别注意一些复杂的对象图,例 ...

  3. 六月计划#1A(6.1-6.8)

    5/35 数学 BZOJ_[HNOI2008]_Cards_(置换+Burnside引理+乘法逆元+费马小定理+快速幂) BZOJ_1005_ [HNOI2008]_明明的烦恼_(组合数学+purfe ...

  4. java.util.concurrent.Exchanger应用范例与原理浅析--转载

    一.简介   Exchanger是自jdk1.5起开始提供的工具套件,一般用于两个工作线程之间交换数据.在本文中我将采取由浅入深的方式来介绍分析这个工具类.首先我们来看看官方的api文档中的叙述: A ...

  5. xcodebuild导出ipa方法

    xcode 5.x版本导出ipa是不需要开发者账号,而xcode6以后导出ipa必须要求选择开发者team,无法绕开,但我们使用xcodebuild命令行可以无视这个限制 环境: mac osx 10 ...

  6. Asp.Net MVC4新特性指南(2):新特性介绍

       上一章讲解了最基本的MVC4说明.今天就介绍下几种新特性的使用例子:   就当大家有MVC3的基础了.在这个基础上在看下面的介绍就容易多了.1.Web API MVC4包括一个更好的解决方案:A ...

  7. Struts2使用拦截器完成权限控制示例

    http://aumy2008.iteye.com/blog/146952 Struts2使用拦截器完成权限控制示例 示例需求:    要求用户登录,且必须为指定用户名才可以查看系统中某个视图资源:否 ...

  8. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程02:关键帧动画导入与切割》

    2. 关键帧动画导入与切割 动画的分割与导入概述: 在游戏当中,游戏角色在不同状态下会有不同的动作,这些动作在引擎里相当于一段段的动画片段.当导入模型资源的时候,连同模型动画都会一并导入到引擎中.开发 ...

  9. Storm系列(十八)事务介绍

    功能:将多个tuple组合成为一个批次,并保障每个批次的tuple被且仅被处理一次. storm事务处理中,把一个批次的tuple的处理分为两个阶段processing和commit阶段. proce ...

  10. ZOJ-3721 Final Exam Arrangement 贪心

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3721 容易的贪心题,排个序.. //STATUS:C++_AC_ ...