再论hashcode,一个意想不到的结果!
class版
- C# code
using System;using System.Collections.Generic;using System.Linq;namespace ConsoleApplication9{ public class B//class版本 { public int i; } class Program { static void Main(string[] args) { List<int> list = new List<int>(); List<B> listClass = new List<B>(); for (int i = 0; i < 10000; i++) { B b = new B(); b.i = i; list.Add(b.GetHashCode()); listClass.Add(b); } Console.WriteLine(list.Distinct().Count());//9999 Console.ReadKey(); } }}
struct版
- C# code
using System;using System.Collections.Generic;using System.Linq;namespace ConsoleApplication9{ public struct B//struct版本 { public int i; } class Program { static void Main(string[] args) { List<int> list = new List<int>(); List<B> listClass = new List<B>(); for (int i = 0; i < 10000; i++) { B b = new B(); b.i = i; list.Add(b.GetHashCode()); listClass.Add(b); } Console.WriteLine(list.Distinct().Count());//10000 Console.ReadKey(); } }}
只改了一个地方class/struct
[解决办法]
1.GetHashCode() 是把对应的值,通过散列算法,变换成固定长度的输出,该输出就是散列值.
不同的输入可能会散列成相同的输出.
2.class和struct:class是引用类型,而struct是值类型
struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针
new一个class的实例时,对象保存了该实例实际数据的引用地址,而对象的值保存在托管堆(managed heap)中
你例子中应该是class,0-9999 数据的引用地址在hash的时候 出现了两个相同的散列值.
在list.Distinct()的时候去重了..
而struct中实例子存的就是值, hash的时候没有出现相同的散列值.
在list.Distinct()没能去重..
[解决办法]
引用类型和值类型在有些地方是有区别的。
[解决办法]
NET Framework 不保证 GetHashCode 方法的默认实现以及它所返回的值在不同版本的 .NET Framework 中是相同的
根据键对象的GetHashTable得到HashCode,如果在存储桶中该地址没有被占用,则将其存入其中
[解决办法]
实际上,地址空间大于int的取值范围,所以GetHashCode()的计算结果是会有重复的——尽管散列的目的就是尽量不重复。
千万不要因此就说两个对象的HashCode就相同哦!那可是一个很简单的误会。