-
C#中Equals和GetHashCode
本站最新发布 C#从入门到精通
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
Equals和GetHashCode
Equals每个实现都必须遵循以下约定:
- 自反性(Reflexive): x.equals(x)必须返回true.
- 对称性(Symmetric): x.equals(y)为true时,y.equals(x)也为true.
- 传递性(Transitive): 对于任何非null的应用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)必须返回true.
- 一致性(Consistence): 如果多次将对象与另一个对象比较,结果始终相同.只要未修改x和y的应用对象,x.equals(y)连续调用x.equals(y)返回相同的值l.
- 非null(Non-null): 如果x不是null,y为null,则x.equals(y)必须为false
GetHashCode:
- 两个相等对象根据equals方法比较时相等,那么这两个对象中任意一个对象的hashcode方法都必须产生同样的整数。
- 在我们未对对象进行修改时,多次调用hashcode使用返回同一个整数.在同一个应用程序中多次执行,每次执行返回的整数可以不一致.
- 如果两个对象根据equals方法比较不相等时,那么调用这两个对象中任意一个对象的hashcode方法,不一同的整数。但不同的对象,产生不同整数,有可能提高散列表的性能.
IEqualityComparer实现
下面我们创建一个学生类,从而进一步的实现我们对象数据的对比
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
通过如下代码我们将通过distinct方法实现我们的过滤.
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>
{
new Student{ Name = "MR.A", Age = 32},
new Student{ Name = "MR.B", Age = 34},
new Student{ Name = "MR.A", Age = 32}
};
Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count());//distinctStudents has Count = 3
Console.ReadLine();
}
}
我们需要达到的是忽略相同数据的对象,但是并没有达到我们如期的效果.因为是distinct默认比较的是对象的引用...所以这样达不到我们预期效果.那我们修改一下来实现我们预期效果.
在默认情况下Equals具有以下行为:
- 如果实例是引用类型,则只有引用相同时, Equals才会返回true。
- 如果实例是值类型,则仅当类型和值相同时, Equals才会返回true。
Distinct
通过使用指定的 IEqualityComparer
类型参数
-
TSource source 的元素类型。
参数
-
source IEnumerable
要从中移除重复元素的序列。 -
comparer IEqualityComparer
用于比较值的 IEqualityComparer 。
返回
-
IEnumerable
一个包含源序列中的非重复元素的 IEnumerable。
我们来看如下代码片段
public class StudentComparator : EqualityComparer<Student>
{
public override bool Equals(Student x,Student y)
{
return x.Name == y.Name && x.Age == y.Age;
}
public override int GetHashCode(Student obj)
{
return obj.Name.GetHashCode() * obj.Age;
}
}
上述代码片段如果两个Equals返回的true并且GetHashCode返回相同的哈希码,则认为两个对象相等.
重写Equals和GetHashCode
var stu1 = new Student { Name = "MR.A", Age = 32 };
var stu2 = new Student { Name = "MR.A", Age = 32 };
bool result = stu1.Equals(stu2); //false because it's reference Equals
上述代码片段执行后结果非预期效果.我们将进一步的去实现代码,以达到预期效果....
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public override bool Equals(object obj)
{
var stu = obj as Student;
if (stu == null) return false;
return Name == stu.Name && Age == stu.Age;
}
public override int GetHashCode()
{
return Name.GetHashCode() * Age;
}
}
var stu1 = new Student { Name = "MR.A", Age = 32 };
var stu2 = new Student { Name = "MR.A", Age = 32 };
bool result = stu1.Equals(stu2); //result is true
我们再使用LINQ Distinct方法进行过滤和查询,同时将会检查Equals和GetHashCode
List<Student> students = new List<Student>
{
new Student{ Name = "MR.A", Age = 32},
new Student{ Name = "MR.B", Age = 34},
new Student{ Name = "MR.A", Age = 32}
};
Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count()); //distinctStudents has Count = 2
作者:@冯辉
栏目列表
最新更新
python数据库连接池技术总结
成人网站性能提升 20 倍之经验谈 [Python
python动态捕获异常
python 探测网站目录的GUI程序
python实现中文字符繁体和简体中文转换
Python服务器开发 -- 网络基础
python高性能编程方法一
使用python管理Cisco设备
python抓取google搜索结果
Python 自动备份SVN版本库并复制到远程主机
基于UDP的服务器端和客户端
再谈UDP和TCP
在socket编程中使用域名
网络数据传输时的大小端问题
socket编程实现文件传输功能
如何优雅地断开TCP连接?
图解TCP四次握手断开连接
详细分析TCP数据的传输过程
图解TCP数据报结构以及三次握手(非常详
TCP协议的粘包问题(数据的无边界性)
Excel数据导入到Sql server
SQL Server like 字段
SQL Server中的LEFT、RIGHT函数
sql server 安装出现需要sqlncli.msi文件,错误
SQL Server学习内容(一)
SQLServer执行大脚本文件时,提示“无法执
数据库敏捷版本控制之3个数据库策略
将select 转为json
SQL Server 创建索引(index)
GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及