C# GetHashCode在对象的生命周期内是否保证相同?
我讨厌打篮球。在@eric lippert的书中,他说: 对象的哈希值在其整个生存期内是相同的 然后跟进: 然而,这只是一个理想的情况指导方针 所以,我的问题是 对于POCO(未重写任何内容)或框架(如C# GetHashCode在对象的生命周期内是否保证相同?,c#,.net-core,C#,.net Core,我讨厌打篮球。在@eric lippert的书中,他说: 对象的哈希值在其整个生存期内是相同的 然后跟进: 然而,这只是一个理想的情况指导方针 所以,我的问题是 对于POCO(未重写任何内容)或框架(如FileInfo或Process)对象,GetHashCode()方法的返回值是否保证在其生命周期内相同 另外,我说的是预先分配的对象变量foo=新条()将foo.GetHashCode()始终返回相同的值。有三种情况 不重写GetHashCode 不重写GetHashCode 重写GetHash
FileInfo
或Process
)对象,GetHashCode()
方法的返回值是否保证在其生命周期内相同
另外,我说的是预先分配的对象<代码>变量foo=新条()将foo.GetHashCode()
始终返回相同的值。有三种情况
GetHashCode
GetHashCode
GetHashCode
GetHashCode
,则使用helper函数RuntimeHelpers.GetHashCode
的返回值。这将在每次为同一对象调用时返回相同的值,因此对象将始终具有相同的哈希代码。请注意,此哈希代码特定于单个AppDomain-重新启动应用程序或创建另一个AppDomain可能会导致对象获得不同的哈希代码
如果结构未重写GetHashCode
,则会根据其成员之一的哈希代码生成哈希代码。当然,如果您的结构是可变的,那么该成员可以随时间而改变,因此哈希代码可以随时间而改变。即使结构是不可变的,该成员本身也可能发生变异,并可能返回不同的哈希代码
如果一个类或结构确实重写了GetHashCode
,那么所有的赌注都是无效的。有人可以通过返回一个随机数来实现GetHashCode
——这有点愚蠢,但这是完全可能的。更有可能的是,对象可以是可变的,其哈希代码可以基于其成员,这两者都可以随时间而改变
对于可变的对象,或者以哈希代码随时间变化的方式(在给定的AppDomain中)实现GetHashCode
,通常是一个坏主意。在这种情况下,Dictionary
等类所做的许多假设都会失效,您可能会看到奇怪的行为。如果您查看,您会发现关于GetHashCode方法的默认行为的以下注释:
如果未重写GetHashCode,则引用类型的哈希代码为
通过调用基类的Object.GetHashCode方法计算,
它根据对象的引用计算哈希代码;更多
有关详细信息,请参阅RuntimeHelpers.GetHashCode。换句话说,两个
ReferenceEquals方法返回true的对象具有
相同的散列码。如果值类型不重写GetHashCode,则
基类的ValueType.GetHashCode方法使用反射
根据类型字段的值计算哈希代码。在里面
换句话说,字段值相等的值类型具有相等的
散列码
根据我的理解,我们可以假设:
- 对于引用类型(不重写Object.GetHashCode) 给定实例的哈希代码的值保证为 在实例的整个生命周期中都是相同的(因为内存 对象的存储地址在运行期间不会更改 寿命)
- 对于值类型(不重写Object.GetHashCode),这取决于:如果值类型是不可变的,则哈希代码不会 在其生命周期内发生变化。如果为,则为其字段的值 可以在创建后更改,则其哈希代码也将更改。 请注意,值类型通常是不可变的