于快速创建 IEqualityComparer<T> 实例的类 Equality<T>
于快速创建 IEqualityComparer<T> 实例的类 Equality<T>
原文中的 Equality<T> 实现如下:
1 |
public static class Equality<T> |
代码中的问题使用红色粗体标出。
在改进之前,我们需要先弄清两个关于 null 值的两个问题:
关于 null 的两个问题
将定有一个 Person 类:
1 |
public class Peron |
问题一,两个 null 值是否相等?
1 |
Peron p1 = new Peron { Name = null };
|
请告诉我 b1 和 b2 的值。
问题二,为 null 时 HashCode 应该是什么?
1 |
var h1 = StringComparer.InvariantCulture.GetHashCode(p1.Name); |
请告诉我 h1 和 h2 的值。
建议大家想下这两个问题,答案就不给出了,自行调试吧。
你的答案和调试得出的结果可能会有出入,如果这样你得好好思考下了。
Equality<T> 改进后的代码
改进后,代码如下:
1 |
public static class Equality<T> |
以上代码黄色高亮部分为新加入代码。
用法:
1 |
var personNameComparer = Equality<Peron>.CreateComparer(p => p.Name); |
第 28 行代码
此行代码会有很大争议,它会影响 p7 与 p8 比较的结果 b4。
也许有的朋友认为应该将这行代码修改为:
1 |
if(x== null) |
这样得出 b4 的值为 true.
我不赞同这种方式,我的观点是:“p=>p.Name”指定使用 Person 的 Name 进行相等比较,Person若不存在(值为 null), Name 更不存在,也谈不上相等,所以应返回 false。
当然还有另一种想法,Person 不存在,没法比,应该抛出异常。
第 33 行代码
也可以写成:
1 |
return RuntimeHelpers.GetHashCode(null); |
RuntimeHelpers 类在 System.Runtime.CompilerServices 命名空间下,我在反编译 Object 时,在 GetHashCode() 方法中发现了它。
复杂情况下的使用
一位园友问我这样一个问题,如下两个类:
1 |
public class Employee |
要创建 Employee 的相等比较器,根据其学校(School)的所在城市(City)。不考虑一个 Employee 多个 School 的情况,但要考虑 Employee 的 School 属性为 null 的情况(可能没上过学)。
用以下方式创建:
1 |
var employeeComparer = Equality<Employee>.CreateComparer(i => i.School.City); |
运行时,可能会出错。执行比较时,遇到 Employee 的 School 属性为 null ,便会抛出 NullReferenceException。
一种可行的写法是:
1 |
var companylComparer = Equality<School>.CreateComparer(i => i.City); |
是的,分两步。也许是麻烦了些,不过试想下如果没有 Equality<T> 类的帮助,如果实现这个这个相等比较器?相当麻烦,不信可以试着写下。
简单测试下:
1 |
var v0 = new Employee { School = new School { City = "Beijing" } };
|
再搞复杂一点
把前面的 City 变成一个类,代码如下:
1 |
public class Employee |
还是要求创建 Employee 的相等比较器,根据 Employee 的 School 的 City 的 Country 来判断。要考虑各引用属性的为 null 时的情形。
还不过瘾,就再加点难度! Country 比较时不考虑大小写。
嘻嘻,有谁能告诉我如何创建,可以使用本文中的 Equality<T>,也可以不用。当然,越简洁越好。
知道的话,请回复我,非常期待你的参与!
于快速创建 IEqualityComparer<T> 实例的类 Equality<T>的更多相关文章
- 快速创建 IEqualityComparer 实例:改进
两年前,我写了篇文章<快速创建 IEqualityComparer<T> 和 IComparer<T> 的实例>,文中给出了一个用于快速创建 IEqualityCo ...
- 一分钟在云端快速创建MySQL数据库实例
本教程将帮助您了解如何使用Azure管理门户迅速创建,连接,配置MySQL 数据库 on Azure.完成本教程后,您将在Azure上拥有一个示例MySQL数据库服务器,并了解如何使用管理门户执行基本 ...
- 工厂模式,根据ID创建对应的实例类
工厂模式,根据ID创建对应的实例类 // // main.cpp // TestCPP1 // // Created by bianchx on 15/4/27. // Copyright (c) 2 ...
- 快速创建SpringBoot2.x应用之工具类自动创建web应用、SpringBoot2.x的依赖默认Maven版本
快速创建SpringBoot2.x应用之工具类自动创建web应用简介:使用构建工具自动生成项目基本架构 1.工具自动创建:http://start.spring.io/ 2.访问地址:http://l ...
- 应用DriverManager类创建sqlserver数据库连接实例 JSP中使用数据库
JSP中使用数据库 1.JDBC介绍 java数据库连接(java Database Connectivity ,JDBC)是一种用于执行SQL语句的JavaAPI ,由一组使用java编程语言编写的 ...
- vs里根据json快速创建对应类的方法
有时候,我们在调用别人接口的时候,服务端返回了一个json格式的字符串,我们要获取json里面的数据的话一般有两种方式: 1.通过正则 2.反序列化成一个对象 第一种方式这里不再多说,主要说一下第二种 ...
- Foundation框架 - 快速创建跨平台的网站页面原型
API参考:http://foundation.zurb.com/docs/ 作为网页设计和开发人员,我们面临着以下几个严峻的问题: 每天,人们用来上网的设备种类和数量都在不断上升. 为每种设备设计开 ...
- 快速创建显示数字数据的动画——CountUp.js
由于项目需求,需要写一个数字增/减量的动画特效,最后找到了CountUp.js CountUp.js是一个无依赖,轻量级的JavaScript“类”,可用于快速创建以更有趣的方式显示数字数据的动画. ...
- 十分钟快速创建 Spring Cloud 项目
一般来说,Intelij IDEA 可以通过 Maven Archetype 来快速生成Maven项目,其实 IDEA 集成了 Spring 官方提供的 Spring Initializr,可以非常方 ...
随机推荐
- java 科学计算库
stackoverflow 上的讨论, 其中不乏lib的作者... http://stackoverflow.com/questions/529457/performance-of-java-matr ...
- Git 基本原理与经常使用命令
平时使用过两种版本号控制软件 SVN 和 Git,平心而论,假设纯粹自己使用,那么绝对 Git 更加适合,本地库.远程库.离线工作.强大而灵活的分支.大名鼎鼎的Github, 这些都是选择 Git 的 ...
- [置顶] Spring中DI设置器注入
Java的反射机制可以说是在Spring中发挥的淋漓尽致,下面要看的代码就是通过反射机制来实现向一个类注入其实际依赖的类型,这个过程的实现会交由Spring容器来帮我们完成. JavaBean中针对属 ...
- 仅当使用了列的列表,并且 IDENTITY_INSERT 为 ON 时,才能在表中为标识列指定显式值问题
今天在处理数据库过程中碰到这样的问题在插入一条数据到表中 系统报这样的错误 仅当使用了列的列表,并且 IDENTITY_INSERT 为 ON 时,才能在表中为标识列指定显式值问题 表有一列是自增长的 ...
- elasticsearch的rest搜索--- 安装
目录: 一.针对这次装B 的解释 二.下载,安装插件elasticsearch-1.7.0 三.索引的mapping 四. 查询 五.对于相关度的大牛的文档 二.安装 1. 安装head管理插 ...
- Jquery--仿制360右下角弹出窗口
原文:Jquery--仿制360右下角弹出窗口 先发浏览器效果图,给大家看. 要实现这样的效果,按照思路,第一步,写好CSS布局,将图片放到浏览器右下角的位置 CSS代码很灵活,我写的只是简单的一种而 ...
- duplicate symbol _*** in:
duplicate symbol _kReachabilityChangedNotification in: 问题出在同一个文件被引用两次,在项目中找到引用的地方,删掉对应的引用
- Beginning Python From Novice to Professional (7) - 类别
类别 创建一个简单的类: #!/usr/bin/env python __metaclass__ = type class Person: def setName(self,name): self.n ...
- LogMaster4Net
使用LogMaster4Net实现应用程序日志的集中管理 日志在软件系统中的重要性我在此也不赘述了,几乎所有程序员每天都会更日志打交道. 那么你是否曾今为这样的一些事情而困扰过: - 远程登录到不同的 ...
- js 里面 写 C# 代码 遇到的问题
js 代码块 必须放置在 body 里面