在.NET中,您需要Equals(object)和GetHashCode()兼容.但有时你不能:
public class GreaterThan32Bits
{
public int X { get; set; }
public int Y { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
因为数据密度大于32位,并且GetHashCode返回Int32,所以您将有3个解决方案(假设正确实现了GetHashCode):
避免将代码重复 丢弃为不正确
public override bool Equals(object other)
{
if(ReferenceEquals(null, other)) return false;
if(ReferenceEquals(this, other)) return true;
return this.GetHashCode() == other.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)与GetHashCode()分开实现Equals
public override bool Equals(object obj)
{
if(ReferenceEquals(null, other)) return false;
if(ReferenceEquals(this, other)) return true;
var other = obj as GreaterThan32Bits;
if(this.X == other.X) return this.Y == other.Y;
return false;
}
Run Code Online (Sandbox Code Playgroud)实现更高精度的GetHashCode64,重写的GetHashCode(32位)将返回(int)GetHashCode64(),而Equals将返回this.GetHashCode64()== other.GetHashCode64()
你会实施哪一个?
第一种解决方案是不精确的不正确,但更清洁.第二个选项看起来很干净,但是当类有更多属性时会变得非常复杂.第三种选择是妥协.
我有以下课程
public class DateRange
{
private DateTime startDate;
private DateTime endDate;
public override bool Equals(object obj)
{
DateRange other = (DateRange)obj;
if (startDate != other.startDate)
return false;
if (endDate != other.endDate)
return false;
return true;
}
...
}
Run Code Online (Sandbox Code Playgroud)
我需要在一个使用DateRange键入的字典中存储一些值,如:
Dictionary<DateRange, double> tddList;
Run Code Online (Sandbox Code Playgroud)
我应该如何覆盖类的GetHashCode()方法DateRange?
抱歉将两个问题合并为一个,它们是相关的.
HashCode对于HashSets等等.据我了解,它们必须是唯一的,而不是更改,并将对象的任何配置表示为单个数字.
我的第一个问题是,我的对象,包含两个Int16s a并且b,它是安全的我GetHashCode回到类似a * n + b,其中n是一个大数,我想也许Math.Pow(2, 16)?
同样GetHashCode似乎也特异性地返回Int32类型.
32位可以存储,例如,两个Int16,一个unicode字符或16个N,S,E,W罗盘方向,它并不多,甚至类似于少量节点图的东西可能对它来说太多了.这是否代表C#Hash集合的限制?
当我在使用旅行时发现我GetHashCode()的类的覆盖方法Foo被调用时,我感到很惊讶 .但在其他情况下不会发生这种情况.为什么?foreachIEnumerable<Foo>
实际代码的某些部分:
var allVolumeImagesInvolvedInMerge = volumeChainsToMerge
.SelectMany(x => x);
var allVolumeImagesNotInvolvedInMerge = allVolumeImagesWithinCell
.Except(allVolumeImagesInvolvedInMerge)
.Where(vi => volumeImagesNotAllowedToDelete.ContainsFast(vi) == false);
var volumeImagesCandidatesForDeletion = allVolumeImagesNotInvolvedInMerge
.Where(x => driverVolumeIds.Contains(x.DriverVolumeId));
var groupedVolumeImagesCandidatesForDeletion = volumeImagesCandidatesForDeletion
.GroupBy(vi => vi.DriverVolumeId);
// here GetHashCode is called
foreach (var group in groupedVolumeImagesCandidatesForDeletion)
{
...
}
Run Code Online (Sandbox Code Playgroud) 以下代码可以吗?
public override bool Equals(object obj)
{
if (obj == null || !(obj is LicenseType))
return false;
return GetHashCode() == obj.GetHashCode();
}
public override int GetHashCode()
{
return
Vendor.GetHashCode() ^
Version.GetHashCode() ^
Modifiers.GetHashCode() ^
Locale.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
所有属性都是枚举/数字字段,并且是唯一定义LicenseType对象的属性.
我有两个不同的对象列表,并希望根据某些属性的权重获得它们的相似性.最快的方式似乎是实现IEquatable接口,这就是我所做的:
public class CompareEntry : IEquatable<CompareEntry>
{
public int LeadId { get; set; }
public int SaleId { get; set; }
public string Email { get; set; }
public string PhonePrivate { get; set; }
public string PhoneMobile { get; set; }
public string PhoneCompany { get; set; }
public string FirstName { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string CompanyName …Run Code Online (Sandbox Code Playgroud) 为什么GetHashCode返回相同类型的不同值.如果我执行此代码:
Console.WriteLine(typeof(Guid).GetHashCode());
Run Code Online (Sandbox Code Playgroud)
在不同的应用程序中,我得到不同的哈希码.
如果我在不同的应用程序中多次执行以下语句:
Console.WriteLine("ABC".GetHashCode());
Run Code Online (Sandbox Code Playgroud)
我总是得到相同的哈希码.但为什么哈希码会改变System.Type,但不是为了System.String?
谢谢.
在这个MSDN页面中,它说:
警告:
如果重写GetHashCode方法,则还应该重写Equals,反之亦然.如果在对两个对象进行相等性测试时,重写的Equals方法返回true,则重写的GetHashCode方法必须为两个对象返回相同的值.
我也看到了许多类似的建议,我可以理解,当重写Equals方法时,我也想要覆盖GetHashCode.据我所知,GetHashCode与哈希表查找一起使用,这与等式检查不同.
这是一个帮助解释我想问的例子:
public class Temperature /* Immutable */
{
public Temperature(double value, TemperatureUnit unit) { ... }
private double Value { get; set; }
private TemperatureUnit Unit { get; set; }
private double GetValue(TemperatureUnit unit)
{
/* return value converted into the specified unit */
}
...
public override bool Equals(object obj)
{
Temperature other = obj as Temperature;
if (other == null) { return false; }
return (Value == other.GetValue(Unit));
}
public …Run Code Online (Sandbox Code Playgroud) 所有资源显示如何覆盖Equals(object)和GetHashCode()使用数字字段来实现该GetHashCode()方法:
实现Equals方法
Equals和GetHashCode的最佳策略是什么?
为什么在重写Equals方法时重写GetHashCode很重要?
但是,在我的课上,我没有任何数字字段.它是树中的节点,引用其父节点,子节点和接口作为数据:
public class Node
{
private IInterface myInterface;
private Node parent;
private List<Node> children = new List<Node>();
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var node = (Node)obj;
return myInterface == node.myInterface;
}
public override int GetHashCode()
{
???
}
}
Run Code Online (Sandbox Code Playgroud)
我应该用什么设置哈希码?
gethashcode ×10
c# ×9
.net ×4
equality ×2
equals ×2
hash ×2
boolean ×1
comparison ×1
dictionary ×1
hashcode ×1
iequatable ×1
int ×1
int32 ×1
linq ×1
performance ×1
types ×1