DictionaryGetHashCode和Equals在C#中的实现#对象比较所必需的。这是我尝试使用FOREACH迭代方法解决的一段代码。但是由于性能问题,我的老板说不要使用任何迭代(可能也使用containskey或containsvalue方法)。任何帮助都非常欢迎..publicclassemployee{publicstringempname{get;放;}公共字符串位置{得到;放;}publicdoublekinid{get;放;}publicdoublemanagerKin{get;放;}publicoverrideboolEquals(objectobj){returnbase.Equals(obj);}publicoverrideintGetHashCode(){returnbase.GetHashCode();}}publicclassmanager{publicstringmanagername{get;放;}publicdoublekinid{get;放;}publicoverrideintGetHashCode(){return17*managername.GetHashCode()+kinid.GetHashCode();}}公共类程序{publicstaticvoidMain(){employeeemp=newemployee();员工emp2=新员工();经理mng=新经理();经理mng2=新经理();emp.empname="迪帕克";emp.location="浦那";emp.kinid=36885;emp.managerKin=007;emp2.??empname="阿斯塔";emp2.??location="浦那";emp2.??kinid=30000;emp2.??managerKin=007;mng.kinid=007;mng.managername="Gaurav";mng2.kinid=001;mng2.managername="苏里亚";字典关系=newDictionary();relations.Add(emp,mng);relations.Add(emp2,mng2);Console.ForegroundColor=ConsoleColor.Yellow;Console.WriteLine("经理的详细信息是:");foreach(varelementinrelations)Console.WriteLine("nKINID:{0}nManager'sName:{1}",element.Value.kinid,element.Value.managername);Console.WriteLine("请输入经理的详细信息..");Console.ForegroundColor=ConsoleColor.Gray;Console.Write("nManager的亲戚:");双mkin=Convert.ToDouble(Console.ReadLine());Console.Write("经理姓名:");字符串mname=Console.ReadLine();经理mng1=新经理();mng1.kinid=mkin;mng1.managername=mname;inthashvalue=17*mname.GetHashCode()+mkin.GetHashCode();#regionBYUSINGFOREACH循环inti=0;foreach(varelementinrelations){if(element.Value.GetHashCode()==hashvalue){i+=1;if(i==1){Console.WriteLine("以下员工向经理报告:{0}",mname);}Console.WriteLine(element.Key.empname+""+element.Key.kinid+""+element.Key.location+""+element.Key.managerKin);}}if(i==0){控制台。WriteLine("抱歉,您输入的经理详细信息"{0}""{1}"在我们的数据库中不存在..",mng1.managername,mng1.kinid);}#endregionConsole.ReadLine();}}for要使用ContainsKey或ContainsValue关键字在字典中搜索对象,编译器使用两个隐式函数,即GetHashCode()和Equals()所以当我们有一个比较对象时,我们需要遮盖这两种方法!!这是代码#region使用字典存储类对象(检查员工是否存在并打印经理的姓名)publicclassemployee{publicstringempname{get;放;}公共字符串位置{得到;放;}publicdoublekinid{get;放;}publicdoublemanagerKin{get;放;}//publicoverrideboolEquals(objectobj)//两个相等方法中的任何一个都有效。//{//员工其他员工;//otheremployee=(employee)obj;//return(otheremployee.kinid==this.kinid&&otheremployee.location==this.location&&otheremployee.empname==this.empname&&otheremployee.managerKin==this.managerKin);//}publicoverrideboolEquals(objectobj)//当运行这整个代码时,在Equals()和GetHashCode()方法上放置一个断点,并查看执行流程。{员工其他员工;otheremployee=(employee)obj;return(obj.GetHashCode()==otheremployee.GetHashCode());}公共覆盖intGetHashCode()//运行这段代码时,在Equals()和GetHashCode()方法上打断点,看执行流程。{//inttemp=base.GetHashCode();//不要使用这个//returnbase.GetHashCode();inttemp=empname.GetHashCode()+location.GetHashCode()+kinid.GetHashCode()+managerKin.GetHashCode();返回温度;}}publicclassmanager{publicstringmanagername{get;放;}publicdoublekinid{get;放;}publicoverrideintGetHashCode(){returnbase.GetHashCode();}publicoverrideboolEquals(objectobj){returnbase.Equals(obj);}}公共类程序{publicstaticvoidMain(){employeeemp=newemployee();员工emp2=新员工();经理mng=新经理();经理mng2=新经理();emp.empname="迪帕克";emp.location="浦那";emp.kinid=36885;emp.managerKin=007;emp2.??empname="阿斯塔";emp2.??location="浦那";emp2.??kinid=30000;emp2.??managerKin=001;mng.kinid=007;mng.managername=“高拉夫”;mng2.kinid=001;mng2.managername="苏里亚";字典关系=newDictionary();relations.Add(emp,mng);//打断点看执行流程relations.Add(emp2,mng2);//打断点看执行流程Console.ForegroundColor=ConsoleColor.Yellow;Console.WriteLine("员工详细信息是:");foreach(varelementinrelations)Console.WriteLine("nEmployeeName:{0}nLocation:{1}nEmployeeKinId:{2}nManager'sKinId:{3}",element.Key.empname,element.Key.location,element.Key.kinid,element.Key.managerKin);Console.WriteLine("请输入员工的详细信息..");Console.ForegroundColor=ConsoleColor.Gray;Console.Write("n员工姓名:");字符串名称=Console.ReadLine();Console.Write("位置:");字符串elocn=Console.ReadLine();Console.Write("员工KinId:");双ekinid=Convert.ToDouble(Console.ReadLine());Console.Write("经理编号:");双emngr=Convert.ToDouble(Console.ReadLine());员工emp1=新员工();emp1.empname=ename;emp1.location=elocn;emp1.kinid=ekinid;emp1.managerKin=emngr;诠释我=0;//此变量用作查找EmployeeKey是否存在的指示器。if(relations.ContainsKey(emp1))//这里打个断点,看执行流程。{Console.WriteLine("员工:{0}存在..",emp1.empname);Console.WriteLine("员工向以下经理报告:{0}n,经理的KinId是{1}。",(relations[emp1]).managername,relations[emp1].kinid);我=1;控制台.ReadLine();}if(i==0){Console.WriteLine("名为{0}的员工的详细信息不存在!!",emp1.empname);控制台.ReadLine();}#endregion要在字典中搜索元素,您可以使用ContainsKey、ContainsValue方法或只编写LINQ查询vardict=(frompairinrelationswherepair.Value.Equals(mng1)selectpair).ToDictionary();为了能够比较2个实例是否相等,您应该重写Equals方法,实现IEquatable也是一个很好的做法当你覆盖Equals时,你也应该覆盖GetHashcode(当你将实例放入字典计算桶时使用此方法)。您不应该使用GetHashcode来比较一个对象的两个实例是否相等;相反,您应该使用Equals(或EqualityComparer,它也将使用Equals方法)。如果您已经实现了GetHashCode和Equals,那么您可以通过执行以下操作来确定字典是否包含特定实例:varmyDictionary=newDictionary();myDictionary.ContainsKey(someKey)或varmySet=newHashSet();mySet.Contains(someManagerObject);Dictionary.ContainsKey(employee)在这里无济于事,因为employee是一个“未知”值,而Contains无济于事,因为它需要一个KeyValuePair并且......再次......没有员工知道。ContainsValue(manager)不会有帮助,因为它不返回任何键,并且由于它不是键,所以它是一个O(n)操作,而不是像ContainsKey那样的O(1)!使用当前结构的唯一方法是使用某种形式的循环,尽管我会这样写://KeyisEmployee,ValueisManager//ThisisO(n)vartheEmployees=relations.Where(rel=>rel.Value.Equals(theManager)).Select(rel=>rel.Key);这仅在管理器具有有效的Equals实现时才有效。请注意,根本没有使用哈希码。(因为不同的对象可能共享相同的散列码,所以只比较散列码不能替代Equals、==或CompareTo!——取决于哪个合适。)如果有很多这样的查询,初始结构可以“反转”。//构建一个反向查找varemployeesForManager=relations.GroupBy(rel=>rel.Value)//GrouponManager.ToDictionary(g=>g.Key,g=>g);//Keyisthegroup'sManager//这是O(1),但只有在[重新]生成employeesForManager之后才有效vartheEmployees=employeesForManager[theManager]这仅在manager具有Equals和GetHashCode的有效实现时才有效。(GetHashCode是必需的,因为管理器对象被用作新字典的键。)至于哪个“更好”——好吧,那要看情况。例如,创建一个仅使用一次的反向查找是愚蠢的。在性能问题之前没有性能问题:编写干净的代码和配置文件。快乐的编码。我相信你最后的回复有误。行return(obj.GetHashCode()==otherermployee.GetHashCode());应该是return(this.GetHashCode()==otherermployee.GetHashCode());这样就可以将这个对象的hash和其他Hi码进行比较。正如您在回复中所写,您似乎在将另一个对象与自身进行比较。以上就是C#学习教程:C#字典中GetHashCode和Equals的实现分享的所有内容,如果对大家有用,需要详细了解C#学习教程,希望大家多加关注——本文是收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
