.net 中的相等性比较
引用相等性和值相等性
// x, y, z 都是引用类型变量
object x = new object();
object y = new object();
object z = x; // 输出 false,x 和 y 不具有引用相等性
Console.WriteLine(object.ReferenceEquals(x, y)); // 输出 true,x 和 z 具有引用相等性
Console.WriteLine(object.ReferenceEquals(x, z)); // 输出 true,x 和自身具有引用相等性
Console.WriteLine(object.ReferenceEquals(x, x));
int i = ;
int j = ;
int k = ; // 输出 false,i 和 j 不具有值相等性
Console.WriteLine(i.Equals(j)); // 输出 true,i 和 k 具有值相等性
Console.WriteLine(i.Equals(k)); // 输出 true,i 和自身具有值相等性
Console.WriteLine(i.Equals(i));
== 和 != 操作符
- 对于字符串以外的引用类型,判断变量是否具有引用相等性
- 对于值类型,判断变量是否具有值相等性
- 对于字符串类型,判断变量是否具有值相等性
Object.ReferenceEquals 静态方法
int i = ; // 输出 false,i 被装箱两次,是两个不同的对象,不具有引用相等性
Console.WriteLine(object.ReferenceEquals(i, i)); // 相当于:
object x = i;
object y = i;
Console.WriteLine(object.ReferenceEquals(x, y));
.net 框架的源码实现中,ReferenceEquals 方法使用 == 操作符进行判断:
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.Versioning.NonVersionable]
public static bool ReferenceEquals (Object objA, Object objB) {
return objA == objB;
}
代码参考:http://referencesource.microsoft.com/#mscorlib/system/object.cs,4d607d6d56a93c7e
字符串相等性
在 .net 中,字符串是引用类型,但 == 运算符和 Equals 方法都使用值相等性对字符串进行比较。默认的比较方式是区分大小写的,有时我们希望进行不区分大小写的比较。因此 String 类还有一个 Equals 方法的重载,允许指定如何对字符串进行相等性比较:
public bool Equals(string value, StringComparison comparisonType)
StringComparison 参数允许指定要使用的区域性、大小写和排序规则。
字符串的例子提示相等性比较不是绝对的,两个相同的对象,可能在一个上下文中相等,而在另一个上下文中不相等。
Object.Equals 实例方法
public virtual bool Equals(Object obj)
这是一个虚方法,具体行为取决于是否进行了重写。Object 中 Equals 方法的实现是,如果参数 obj 与当前对象是同一实例,则返回 true。
ValueType 重写了 Equals 方法:若两个值类型变量的类型相同,并且所有实例字段相等,则它们具有值相等性。ValueType 中的 Equals 方法使用反射实现,对性能略有影响。对于自定义值类型,可考虑重写 Equals 方法避免反射带来的性能损失。
Object.Equals 静态方法
这是实用工具性质的方法,用于判断两个变量是否相等,方法签名是:
public static bool Equals(Object objA, Object objB)
public static bool Equals(Object objA, Object objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
重写 Object.Equals 实例方法
重写 Object.Equals 实例方法时,应遵循以下规则:
- 自反:x.Equals(x) 应返回 true
- 对称:x.Equals(y) 和 y.Equals(x) 应具有相同的结果
- 传递:如果 x.Equals(y) 为 true,并且 y.Equals(z) 为 true,那么 x.Equals(z) 应为 true
- 稳定:如果 x 和 y 未修改,那么连续调用 x.Equals(y) 应具有相同的结果
- 当实参为 null 时,应始终返回 null。
- 若重写 Equals 方法,那么还应重写 GetHashCode 方法,并且,两个相等对象的 GetHashCode 方法应返回相同的值
IEquatable<T> 泛型接口
IEquatable<T> 定义类型特定的相等性比较方法,此接口只定义了一个方法,签名为:
bool Equals(T other)
此接口是从 .net 2.0 开始伴随泛型集合引入的。在泛型集合上调用 Contains、IndexOf、LastIndexOf 和 Remove 等方法时,将使用此接口进行相等性比较。根据 MSDN 的说明,任何可能存储在泛型集合中的类都应实现此接口。
如果实现了 IEquatable 接口,还应重写 Object.Equals 实例方法和 Object.GetHashCode 方法。
IEqualityComparer<T> 泛型接口和 EqualityComparer<T> 泛型类
IEqualityComparer 声明了两个方法:
bool Equals(T x, T y)
int GetHashCode(T obj)
此接口允许在泛型集合中跳过 T 本身的 Equals 和 GetHashCode 实现,如果向泛型集合提供了 IEqualityComparer<T> 的实例,那么集合将使用 IEqualityComparer<T> 的 Equals 和 GetHashCode 方法进行比较。
EqualityComparer<T> 为 IEqualityComparer<T> 泛型接口的实现提供基类。EqualityComparer<T>.Default 属性返回默认的相等性比较器,IEquatable<T> 与泛型集合的配合实际上是在这里起作用的:
- 若 T 实现了 IEquatable<T> 接口,则 EqualityComparer<T>.Default 使用 IEquatable<T> 接口进行相等性比较
- 否则,EqualityComparer<T>.Default 使用 Object.Equals 进行相等性比较
.net 中的相等性比较的更多相关文章
- spring中的传播性 个人认为就是对方法的设置 其作用能传播到里面包含的方法上
spring中的传播性 个人认为就是对方法的设置 其作用能传播到里面包含的方法上
- 如何在Django模型中管理并发性 orm select_for_update
如何在Django模型中管理并发性 为单用户服务的桌面系统的日子已经过去了 - 网络应用程序现在正在为数百万用户提供服务,许多用户出现了广泛的新问题 - 并发问题. 在本文中,我将介绍在Django模 ...
- 【软件构造】第三章第五节 ADT和OOP中的等价性
第三章第五节 ADT和OOP中的等价性 在很多场景下,需要判定两个对象是否 “相等”,例如:判断某个Collection 中是否包含特定元素. ==和equals()有和区别?如何为自定义 ADT正确 ...
- Flume-NG中Transaction并发性探究
我们曾经在Flume-NG中的Channel与Transaction关系(原创)这篇文章中说了channel和Transaction的关系,但是在source和sink中都会使用Transaction ...
- 探究CSS中的包裹性
之前一直都知道css中的部分元素具有包裹性,今天写博客的时候正好也遇到了一个,所以想总结一下,有错误的地方欢迎指出来. 什么是包裹性? 包裹性就是父元素的宽度会收缩到和内部元素宽度一样. 哪些元素具有 ...
- css中的层叠性及权重的比较
假如同一个标签被多个选择器选中,每个选择器都设置了相同的样式,浏览器中加载时这个样式听谁的? 不同选择器设置的同一个样式,只会选择一个进行加载,不会叠加. 为了解决听谁的问题,引入层叠性的概念. 层叠 ...
- 前端设计师如何提高UI界面中的阅读性
阅读体验是ui设计中必不可少的一项,良好的设计应该都是可读的设计,如果信息都无法正常而清晰的传达,那么设计就失去了意义.设计的可读性和排版设计息息相关,这也就跟设计师的设计功底息息相关.下面简单介绍文 ...
- JavaScript中各存在性函数
JavaScript中有很多表示存在性和从属关系的函数,本文介绍如下几个: 1)有关实例与构造函数原型之间的关系:isPrototypeOf(),Object.getPrototypeOf(); 2) ...
- JS中的相等性判断===, ==, Object.is()
首发地址:http://www.geeee.top/2019/11/15/equality-comparisons/,转载请注明出处 相信刚接触JS的人都会被他的想等性判断给整糊涂,看看下面代码,你能 ...
随机推荐
- HTML5资源教程
新款CSS3按钮组合 5组可爱CSS3按钮 Leave a reply 之前我分享过一些时尚的CSS3动画按钮,比如CSS3渲染Checkbox实现3D开关切换按钮.纯CSS3 3D按钮 按钮酷似牛奶 ...
- [OpenGL]配置GLFW
注:本文可转载,转载请著名出处:http://www.cnblogs.com/collectionne/p/6937644.html.本文还会修改,如果不在博客园(cnblogs)发现本文,建议访问上 ...
- WPF 杂谈——Binding表达式
不管是定义控件还是用户控件都会用到一个功能--绑定(Binding).书面的叫法:元素绑定.意思就是让绑定的元素实现数据同步.在笔者看来WPF引入这一个功能实在是太完美了.编程更加的具体化.特别是跟M ...
- tostring方法
//__tostring()方法//输出内容时不报错 用法实例:class Ren{ public $name; public function __tostring() { return " ...
- angularjs应用prerender.io 搜索引擎优化实践
上一篇博文(http://www.cnblogs.com/ideal-lx/p/5625428.html)介绍了单页面搜索引擎优化的原理,以及介绍了两个开源框架的优劣.prerender框架的工作原理 ...
- python 标准库 -- multiprocessing
multiprocessing 与 threading.Thread 类似 multiprocessing.Process 创建进程, 该进程可以运行用 python 编写的函数. multiproc ...
- css实现选项卡
<style> *{ margin: ; padding: ; text-decoration: none; list-style: none; outline:none; } .box{ ...
- 探索Windows命令行系列(2):命令行工具入门
1.理论基础 1.1.命令行的前世今生 1.2.命令执行规则 1.3.使用命令历史 2.使用入门 2.1.启动和关闭命令行 2.2.执行简单的命令 2.3.命令行执行程序使用技巧 3.总结 1.理论基 ...
- MySQL如何有效的存储IP地址及字符串IP和数值之间如何转换
mysql> select inet_aton('192.168.0.1'); +--------------------------+ | inet_aton('192.168.0.1') | ...
- CSS active选择器与CSS hover选择器
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...