首页
学习
活动
专区
圈层
工具
发布

原 GetHashCode重写指南(译文)

但是, 当 CLR 类型系统设计时, 没有泛型类型, 因此需要能够存储任何对象的通用哈希表。 哈希表及某些数据结构如何使用 GetHashCode? 假定一个数据类型“set”。...然而,这只是个理想情况,实际上确是: Rule:当对象包含在依赖于哈希代码保持稳定的数据结构中时, GetHashCode 返回的整数决不能更改 使一个对象的hash值随着对象的字段变化而变化是可行的,...如果在两个不同的进程中使两个这样的对象具有完全相同的数据, 则它们不必返回相同的哈希代码。...这是很常见的散列码的结合一起异或他们,但这未必是一件好事。假设您有一个数据结构,其中包含发送地址和家庭地址的字符串。即使在单个字符串的哈希算法是非常好的,如果存在大量两个字符串相同的对象,这些对象的。...当数据结构存在冗余时,异或可以产生或加剧分发问题。

1.3K60

C#记录类型与集合的深度解析:从默认行为到自定义比较

、GetHashCode等完整实现 // 包含解构方法和with表达式支持}(此处保留了完整的类结构说明但压缩了具体实现细节)记录类型的相等性比较如上所示,记录类型默认使用EqualityComparer...ImmutableList本身没有重写Equals和GetHashCode方法——因此具有引用相等语义。...我真正需要的是使用元素类型的相等比较器,判断两个不可变列表在元素数量相同且元素成对相等时视为相等。这很容易实现——连同合适的GetHashCode方法。...添加新属性时必须记得修改这两个方法(我至少忘记过一次)——而如果使用默认生成实现,添加新属性就非常简单。...字符串序数比较字符串比较让我紧张。虽然默认字符串比较对Equals和GetHashCode使用序数比较,但对CompareTo使用文化敏感比较。由于我几乎总是想要序数比较,因此喜欢明确指定。

15510
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C#核编之内建数据类型

    这个随笔中的重点之一是说明:C#中所提供的关键字都是相应系统类型的简化符号(如int是System.Int32类型的简化符号) 一、内建数据类型与层级结构 所有的C#内建数据类型都支持默认的构造函数,简而言之...以上所有的类型都派生自System.Object,它定义了一组.NET基础类库中所有类型都具有的方法(如:ToString()、Equals()、GetHashCode()等),下面通过一段简单的代码来了解一些这些基础方法...尽管大多数应用程序都不需要使用BigInteger结构,但一旦需要定义较大的数值时,这个时候做的第一件事就是导入System.Numberics.dll程序集的引用,在添加using指令,之后就可以通过...但是当你定义一个整数(如500),运行时将其默认设为int数据类型,同样,当设置(66.66)运行时则将其默认设置为double类型.这是C#内部的自动识别数据类型机制,虽然你是用的是BigInterger...+、-、*,因此,在对两个大树执行生发运算时,不必调用Biteger.Multiply();

    1.2K60

    什么是.NET的强类型字符串(Strongly typed string)?

    在.NET中,强类型字符串(Strongly typed string)并不是一个官方的概念,是指使用特定的结构来表示某种类型字符串数据的编码实践。...类似于枚举,可以提供编译时检查类型,减少运行时错误,以及更好的可读性和维护性。相比于枚举,具有更好的扩展性以及更强的约束性。...枚举# 枚举提供了一种便捷的方法来使用相关常数集并将常数值与名称相关联,具有类型安全、可读性高以及编译时检查等优点。...为了让强类型字符串在通用代码的语言结构上看起来更像字符串或者枚举,需要为强类型字符串覆写相等运算符。...根据《框架设计指南》建议:当基类支持一组固定的输入参数,但是派生类需要支持更多的参数时,建议使用强类型字符串;当仅由密封类型使用时,只需要使用预定义的值,枚举将是更好的选择。

    26300

    如何重写object虚方法

    在 C# 中 Object 是所有类的基类,所有的结构和类都直接或间接的派生自它。...当我们在对象上调用 ToString 时默认返回的是类的完全限定名称,比如说我们在 System.IO.File 对象上调用这个方法,就会返回字符串 System.IO.File ,这个结果往往并不是我们所需要的结果并且这个结果也没有什么意义...1.同一和相等 所谓的同一指的是两个对象如果引用的是同一个实例,那么我们就说这两个对象具有同一性。...但是同一只是相等的一种,因为在某些情况下两个对象的部分值或者全部值相等但引用不同,我们也可以说它们具有相等性。下面我们来看一个例子,这个例子通过重写相等性来实现两个对象的相等性。...Equals 判断两个对象是否相等,可以使用 Equals ,通过它可以判断出两个对象是否具有相同的数据。

    1.2K10

    算法和数据结构: 十一 哈希表

    所以下面来讲解如何解决哈希碰撞: 避免哈希冲突 拉链法 (Separate chaining with linked lists) 通过哈希函数,我们可以将键转换为数组的索引(0-M-1),但是对于两个或者多个键具有相同索引值的情况...如果存入的键少于预期,索然有些浪费空间,但是查找速度就会很快。所以当内存不紧张时,我们可以选择足够大的M,可以使得查找时间变为常数,如果内存紧张时,选择尽量大的M仍能够将性能提高M倍。...开放寻址法中最简单的是线性探测法:当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中的下一个位置即将索引值加1,这样的线性探测会出现三种结果: 命中,该位置的键和被查找的键相同 未命中,键为空...实现线性探测法也很简单,我们只需要两个大小相同的数组分别记录key和value。...下面是BCL中string类型的GetHashCode方法的实现,可以看到,当碰撞超过一定次数的时候,就会开启条件编译,对哈希函数进行随机化。

    1.2K20

    C++CLI(一)-C++CLI简介

    对一个引用类来说,相等性是通过函数Equals来实现的,而不是重载==操作符,如标记8(a)所示。...nullptr关键字表示常量空值,当使用在一个句柄上下文中时,它表示空句柄——没有指向任何对象的句柄;当使用在一个指针上下文中时,它表示空指针——没有包含任何地址的指针。...为使哈希表(散列表)数据结构工作正常,在对象中必须有一个名为GetHashCode的函数。...这个函数称为ToString,它的功能是创建并返回一个当前实例的字符串,它调用了System::String::Concat连接三个字符串及两个int,实现了所需功能。...垃圾回收:由句柄p1引用的内存驻留于托管堆中,而托管堆则处于垃圾回收器“监视”之下,当一个句柄超出作用域时,其引用的内存就少了一个与此相联的句柄,继而当句柄计数为零时,内存就被自动回收了。

    3.4K30

    归纳一下:C#线程同步的几种方法

    (【转自www.bitsCN.com 】)因此,当多线程同时访问该变量时,都将直接操作主存,从本质上做到了变量共享。   ...特别是不要使用字符串作为lock的参数,因为字符串被CLR“暂留”,就是说整个应用程序中给定的字符串都只有一个实例,因此更容易造成死锁现象。建议使用不被“暂留”的私有或受保护成员作为参数。...(Object o,[int])的一个重载方法,该方法尝试获取o对象的独占权,当获取独占权失败时,将返回false。   ...在方法中Sleep(1000)是为了在第一个线程还在方法中时,第二个线程能够有足够的时间进来。对每个方法分别起了两个线程,我们先来看一下结果: ?...它们之间的区别可以查看MSDN。当调用事件的 Set方法时,事件将变为终止状态,等待的线程被唤醒。   来看一个例子,这个例子是MSDN上的。

    2.5K31

    dotnet C# 实现 GetHashCode 的方法

    本文来聊聊在重写某个类的 GetHashCode 方法时,可以如何实现 GetHashCode 的返回值 按照 GetHashCode 方法的原则,要求两个对象如果 Equals 返回 true 那么一定要求...当然,反过来不成立,也就是两个对象返回的 GetHashCode 的值相同,对象可以是不相等的 实现 GetHashCode 方法的方式有很多,最简单的就是通过调用基类的 GetHashCode 方法,...} 如上面代码,返回的就是 IntValue 的 GetHashCode 的值 而如果期望有自己的定制化,可以通过 HashCode 结构体实现定义,例如在 Program 类里面有属性定义如下...HashCode 值 如果 HashCode 做不到自己需要的特殊需求,也可以自己动手,毕竟只要返回一个 int 值就可以,只要两个相等的对象返回的 int 值是相同的就没锅 public readonly...而 TextImageFile 和 BackgroundImageFile 都是路径字符串,应该忽略大小写,但 Name 属性是区分大小写的,通过 StringComparer 静态类的辅助可以协助计算出值

    99830

    【《Effective C#》提炼总结】提高Unity中C#代码质量的21条准则

    ● as和is操作符都不会执行任何用户自定义的转换,它们仅当运行时类型符合目标类型时才能转换成功,也不会在转换时创建新的对象。...● 仅当不能使用as进行转换时,才应该使用is操作符。否则is就是多余的。...● 实现自己的GetHashCode( )时,要遵循上述三条原则: 1)如果两个对象相等(由operation==定义),那么他们必须生成相同的散列码。否则,这样的散列码将无法用来查找容器中的对象。...而抽象基类可以为派生类提供一些具体的实现。 3)基类描述并实现了一组相关类型间共用的行为。接口则定义了一组具有原子性的功能,供其他不相关的具体类型来实现。...● 共有四种不同的策略可以防止类型内部的数据结构遭到有意或无意的修改: 1)值类型。当客户代码通过属性来访问值类型成员时,实际返回的是值类型的对象副本。 2)常量类型。如System.String。

    2.6K30

    探究 C# 中的 char 、 string(一)

    System.Char 字符 char 是 System.Char 的别名。 System.Char 占两个字节,16个二进制位。 System.Char 用来表示、存储一个 Unicode 字符。...其他类型无法隐式转为 char 类型,但是任何整型和浮点型都可以显式转为 char。 2. 字符处理 System.Char 中,具有很多就态方法,能够有助于识别、处理字符。...使用 System.Char 中的方法处理字符时,可以调用带有 Invariant 后缀的方法或使用 CultureInfo.InvariantCulture,以进行与语言环境无关的字符处理。...CLR 中维护着一个叫做驻留池(Intern Pool)的表。 这个表记录了所有在代码中使用字面量声明的字符串实例的引用。 拼接方式操作字面量时,新的字符串又会进入字符串驻留池。....GetHashCode() 来对比两个字符串是否为同一个引用。

    1.4K20

    C# 9.0新特性详解系列之五:记录(record)和with表达式

    当一个类型的对象在创建时被指定状态后,就不会再变化的对象,我们称之为不可变类型。这种类型是线程安全的,不需要进行线程同步,非常适合并行计算的数据共享。它减少了更新对象会引起各种bug的风险,更为安全。...这是因为记录有着如下优点: 在构造不可变的数据结构时,它的语法简单易用。 record为引用类型,不用像值类型在传递时需要内存分配,并进行整体拷贝。...2.2 with表达式 当使用不可变的数据时,一个常见的模式是从现存的值创建新值来呈现一个新状态。...结构重写了这个方法,通过递归调用每个结构字段的Equals方法,从而有了“基于值的相等”。Recrods也是这样。这意味着只要他们的值保持一致,两个record对象可以不是同一个对象实例就会相等。...该属性用来在判断两个具有继承关系不同类型的record相等时,该record所依据的类型。

    1.5K60

    分享一篇开发杂文

    ,会造成不必要的时间消耗 当数据源(如DataTable、Array、List、ObservableCollection或其他IListSource等)被绑定到控件时,批量操作数据时应该断开绑定或挂起控件的刷新...1.1.1.4 使用StringBuilder做字符串连接  1.1.2 不要使用空析构函数 ★  如果类包含析构函数,由创建对象时会在 Finalize 队列中添加对象的引用,以保证当对象无法可达时...该方法内部会计算总的 String 长度,仅分配一次,并不会如通常想象的那样分配三次。作为一个经验值,当字符串连接操作达到 10 次以上时,则应该使用 StringBuilder。 ...从实际经验看,使用Hashtable时,Equals方法的消耗一般会占到一半以上。 System.Object类提供了默认的GetHashCode实现,使用对象在内存中的地址作为散列码。...当然,最终还是会实现一个高效的GetHashCode方法的。

    1.1K10

    【愚公系列】2023年11月 数据结构(七)-哈希表

    数组(Array):是一种线性数据结构,它将一组具有相同类型的数据元素存储在一起,并为每个元素分配一个唯一的索引。数组的特点是具有随机访问的能力。...图(Graph):是一种由节点和边组成的非线性数据结构,它可以用来表示各种实体之间的关系,如社交网络、路线图和电路图等。图的遍历和最短路径算法是常见的图算法。...当哈希冲突发生时,会导致哈希表的性能下降,因为需要额外的时间来解决冲突。扩容是为了减少哈希冲突的发生,当哈希表中的元素数量超过了哈希表的负载因子阈值时,会触发扩容机制。...但是,它需要额外的空间存储链表结构,而且当同义词链过长时,查询效率会降低,因此需要合理设置哈希表大小和调整哈希函数,以尽量减少哈希冲突的发生。...字典:哈希表可以用于实现字典,将字符串映射为对应的键值对。键值存储:键值存储通常使用哈希表实现,以快速查找相应键值对应的数据。

    60711

    编写代码良好习惯——C#

    的空字符串;   九、相等判断的多种表示关系   1、ReferenceEquals()判断引用相等,需要两个是引用同一个对象时方可返回true;   2、静态的Equals()方法先进性引用判断再进行值类型判断的...;   3、对于引用类型的判断可以在使用值语义时使用重写Equals()方法;   4、重写Equals()方法时也应当重写GetHashCode()方法,同时提供operater==()操作。   ...十、理解GetHashCode()方法的缺陷   1、GetHashCode()仅应用在基于散列的集合定义键的散列值,如HashTable或Dictionary;   2、GetHashCode()应当遵循相应的三条规则...;   3、当程序更加灵活的添加和删除项时,可以使更加健壮的集合类型,当创建一个模拟集合的类时,应当为其实现索引器和IEnumberable接口。   ...四十一、DataSet优于自定义结构   1、DataSet有两个缺点个:使用XML序列化机制的DataSet与非.NET 代码之间的交互不是很好;DataSet是一个非常通用的容器;   2、强类型的

    97431

    编写高质量代码改善C#程序的157个建议

    本文主要学习记录以下内容:   建议10、创建对象时需要考虑是否实现比较器   建议11、区别对待==和Equals   建议12、重写Equals时也要重写GetHashCode 建议10、创建对象时需要考虑是否实现比较器...假如有姓名、工资两个字段,然后根据工资进行排序那么按照现在的情况来看,ArrayList是无法实现的。所以接口IComparable现在可以派上用场了。...代码运行的时候,CRL首先会调用Person类型的GetHashCode,由于发现Person没有实现GetHashCode,所以CLR最终会调用Object的 GetHashCode方法。...所以,在上面的代码中,两个mike兑现虽然属性值都一致,但是它们默认实现的HashCode不一致,这就导致Dictionary中出现异常的行为。 想要修正该问题,就必须重写GetHashCode方法。...(str2.GetHashCode()); 这两个字符串产生的HasCode是一样的。

    58440
    领券