首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

再论hashcode,一个意想不到的结果!该如何解决

2012-01-28 
再论hashcode,一个意想不到的结果!class版C# codeusing Systemusing System.Collections.Genericusing S

再论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就相同哦!那可是一个很简单的误会。

热点排行