[CLR via C#]5.4 对象哈希码和dynamic基元类型

原文:[CLR via C#]5.4 对象哈希码和dynamic基元类型

  FCL的设计者认为,如果能将任何对象的任何实例放到一个哈希表集合中,会带来很多好处。为此,System.Object提供了虚方法GetHashCode,它能获取任意对象的Int32哈希值。

  如果你重写了Equals方法,那么还应重写GetHashCode方法。因为在System.Collection.Hashtable类型、System.Collections.Generic.Dictionary类型以及其他一些集合实现中,要求两个对象为了相等,必须具有相同的哈希码,所以重写了Equals,那么还应该重写GetHashCode,确保相等性算法和对象哈希码算法是一致的。

 

  System.ValueType实现的GetHashCode采用了反射机制(它的速度较慢),并对类型的实例字段执行的XOR运算。建议自己实现GetHashCode,这样才能确切的掌握它所做的事,而且你的实现会比ValueType的实现快一些。

 

  在自己实现哈希表集合时,或调用GetHashCode,千万不要对哈希码进行持久化,因为哈希码很容易改变。

  为了方便开发人员使用发生或者与基本组件通信,C#编译器允许将一个表达式的类型标记为dynamic.还可将一个表达式的结果放在一个变量中,并将变量的类型标记为dynamic,然后,可以用这个dynamic表达式/变量调用一个成员,比如字段、属性/索引器、方法、委托等。

  代码使用dynamic表达式/变量调用一个成员时,编译器会生成特殊的IL代码来描述所需要的操作。这种特殊的代码称为payload(有效载荷)。在运行时,payload代码根据当前有dynamic表达式/变量引用的对象的实际类型来决定具体执行的操作。

   不要混淆dynamic和var。用var声明的局部变量只是一种简化语法,它要求编译器根据一个表达式推断具体的数据类型。var关键字只能用于声明方法内部的局部变量,而dynamic关键字可用于局部变量,字段和参数。表达式不能转型为var,但可以转型为dynamic。必须实现初始化化var声明的变量,但无需初始化用dynamic声明的变量。

  dynamic表达式其实与System.Object一样的类型。编译器假定你在表达式上进行任何操作都是合法的,所以不会生成任何警告和错误。但是试图在运行时执行无效操作,就会抛出异常。

  不能定义对dynamic进行扩展的扩展方法,但可以定义对Object进行扩展的扩展方法。

  不能讲Lambda表达式或者匿名方法作为实参传给dynamic方法调用,因为编译器不能推断出要使用的类型。

  C#内建的动态求值功能所产生的额外开销是不容忽视的。虽然能用动态功能简化语法,但也要看是否值得。

时间: 2024-11-02 20:27:47

[CLR via C#]5.4 对象哈希码和dynamic基元类型的相关文章

[CLR via C#]5.1 基元类型

原文:[CLR via C#]5.1 基元类型 某些数据类在开发中非常常用,以至于许多编译器允许代码已简化的语法来操作它们.例如可以使用以下语法来分配一个整数: System.Int32 a = new System.Int32(); 当然,你肯定不愿意使用这种语法,C#允许使用如下所示的语法: int a = 0; 这种语法不仅增强代码的可读性,而且生成的IL代码和是有System.Int32时生成的IL代码是完全一致的. 编译器直接支持的数据类型称为基元类型(primitive type).

详解Java中用于查找对象哈希码值的hashCode()函数_java

理解hashCode() 的作用是获取哈希码,也称为散列码:它实际上是返回一个int整数.这个哈希码的作用是确定该对象在哈希表中的索引位置. hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数. 虽然,每个Java类都包含hashCode() 函数.但是,仅仅当创建并某个"类的散列表"(关于"散列表"见下面说明)时,该类的hashCode() 才有用(作用是:确定该类的每一个对象在散列表中的位

CLR笔记:5.基元,引用和值类型

5.1基元类型 编译器(C#)直接支持的任何数据类型都称为基元类型(primitive type),基元类型直接映射到FCL中存 在的类型.可以认为 using string = System.String;自动产生. FCL中的类型在C#中都有相应的基元类型,但是在CLS中不一定有,如Sbyte,UInt16等等. C#允许在"安全"的时候隐式转型--不会发生数据丢失,Int32可以转为Int64,但是反过来要显示 转换,显示转换时C#对结果进行截断处理. unchecked和che

局部敏感哈希之分层法与哈希码法

学到现在越来越感觉计算机网络.操作系统的重要性,组成原理到没感觉出来,求推荐资料,我想要的是描述性解释,教材不是我想要的,谢谢! 感觉自己的知识很老旧,在没有出国也没去高水平大学的条件下,只能通过网络学习了,感谢博客园. 一.检索分类 在检索技术中,索引一直需要研究的核心技术.当下,索引技术主要分为三类:基于树的索引技术(tree-based index).基于哈希的索引技术(hashing-based index)与基于词的倒排索引(visual words based inverted in

jquery获取对象的方法足以应付常见的各种类型的对象_jquery

(1)基本对象获取$("*") 获取所有对象 $("#element") 获取id为element的对象等同于document.getElementById("element"): $(".abc") 获取class为abc的对象 $("div") 获取html中所有的div元素 $("#a,.b,p") 获取id为a和class为b以及所有p元素 $("#a .b p&quo

对象-java源码中一个抽象类初始化方法中包含一个super(),该怎么理解

问题描述 java源码中一个抽象类初始化方法中包含一个super(),该怎么理解 package org.apache.http.params; import java.util.Set; /** * Abstract base class for parameter collections. * Type specific setters and getters are mapped to the abstract, * generic getters and setters. * * @si

WCF 设计和实现服务协定(01)

WCF 术语:• 消息 – 消息是一个独立的数据单元,它可能由几个部分组成,包括消息正文和消息头.• 服务 – 服务是一个构造,它公开一个或多个终结点,其中每个终结点都公开一个或多个服务操作.• 终结点 – 终结点是用来发送或接收消息(或执行这两种操作)的构造. 终结点包括一个定义消息可以发送到的目的地的位置(地址).一个描述消息应如何发送的通信机制规范(绑定)以及对于可以在该位置发送或接收(或两者皆可)的一组消息的定义(服务协定)- 该定义还描述了可以发送何种消息. – WCF 服务作为一个终

[CLR via C#]14. 字符、字符串和文本处理

原文:[CLR via C#]14. 字符.字符串和文本处理 一.字符 在.NET Framewole中,字符总是表示成16位Unicode代码值,这简化了国际化应用程序的开发. 每个字符都表示成System.Char结构(一个值类型) 的一个实例.System.Char类型提供了两个公共只读常量字段:MinValue(定义成"\0")和MaxValue(定义成'\uffff').   针对Char的一个实例,可以调用GetUnicodeCategory方法,这个方法返回的是Syste

CLR笔记:18.可空值类型

前言:System.Nullable<T>在FCL中的实现: System.Nullable<T> where T:struct,所以Nullable<T>是一个值类型 有两个只读属性HasValue和Value,以及GetValueOrDefault方法 18.1 C#语法:Int32? 等价于 Nullable<Int32>,于是可以有: Int32? a = 5; Int32? b = null; 允许类型转换:Int32 c = (Int32)a;