问题描述
我有一个包含以下两个属性的类:
公众诠释标识{搞定;私人集; }
大众T []值{搞定;私人集; }
我已 IEquatable< T>
并重写了的Object.Equals
是这样的:
公共覆盖布尔等于(obj对象)
{
返回的equals(OBJ作为SimpleTableRow< T>);
}公共布尔等于(SimpleTableRow< T>其他)
{
//检查是否为空
如果(的ReferenceEquals(其他,NULL))
返回false; //检查相同的参考
如果(的ReferenceEquals(这一点,其他))
返回true; //检查相同的ID和相同的价值观
返回标识== other.Id&放大器;&安培; Values.SequenceEqual(other.Values);
}
有覆盖当的Object.Equals
我还必须重写 GetHash code
当然。但是,code我应该实现?如何创建一个散列code OUT通用阵列?我如何使用编号
整数结合起来呢?
公共覆盖INT GetHash code()
{
返回//什么?
}
由于该线程中提出的问题,我张贴展示,如果你弄错了......主要是发生什么事,另一个回答,你不能使用数组的 GetHash code()
;正确的行为是,当你运行它...切换的意见来解决它没有任何警告的印刷:
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
静态类节目
{
静态无效的主要()
{
//第一和第二逻辑上都相同
SimpleTableRow< INT>第一=新SimpleTableRow&所述; INT>(1,2,3,4,5,6),
第二=新SimpleTableRow&所述; INT>(1,2,3,4,5,6); 如果(first.Equals(二)及和放大器;!first.GetHash code()= second.GetHash code())
{//证明平等相待,但GetHash code()不同意
Console.WriteLine(我们有一个问题);
}
HashSet的< SimpleTableRow< INT>>设置=新的HashSet< SimpleTableRow< INT>>();
set.Add(第一);
set.Add(第二);
//这混淆任何使用散列算法
如果(set.Count = 1!)Console.WriteLine(是的,非常糟糕确实);
}
}
类SimpleTableRow< T> :IEquatable< SimpleTableRow< T>>
{ 公共SimpleTableRow(INT ID,则params T []值){
this.Id = ID;
this.Values =值;
}
公众诠释标识{搞定;私人集; }
大众T []值{搞定;私人集; } 公共覆盖INT GetHash code()//错误
{
返回Id.GetHash code()^ Values.GetHash code();
}
/ *
公共覆盖INT GetHash code()//右
{
INT哈希= ID;
如果(值!= NULL)
{
哈希=(散* 17)+ Values.Length;
的foreach(中值T(T))
{
哈希* = 17;
如果(T!= NULL)哈希散列= + t.GetHash code();
}
}
返回哈希;
}
* /
公众覆盖布尔等于(obj对象)
{
返回的equals(OBJ作为SimpleTableRow< T>);
}
公共布尔等于(SimpleTableRow< T>其他)
{
//检查是否为空
如果(的ReferenceEquals(其他,NULL))
返回false; //检查相同的参考
如果(的ReferenceEquals(这一点,其他))
返回true; //检查相同的ID和相同的价值观
返回标识== other.Id&放大器;&安培; Values.SequenceEqual(other.Values);
}
}
I have a class that contains the following two properties:
public int Id { get; private set; }
public T[] Values { get; private set; }
I have made it IEquatable<T>
and overriden the object.Equals
like this:
public override bool Equals(object obj)
{
return Equals(obj as SimpleTableRow<T>);
}
public bool Equals(SimpleTableRow<T> other)
{
// Check for null
if(ReferenceEquals(other, null))
return false;
// Check for same reference
if(ReferenceEquals(this, other))
return true;
// Check for same Id and same Values
return Id == other.Id && Values.SequenceEqual(other.Values);
}
When having override object.Equals
I must also override GetHashCode
of course. But what code should I implement? How do I create a hashcode out of a generic array? And how do I combine it with the Id
integer?
public override int GetHashCode()
{
return // What?
}
Because of the problems raised in this thread, I'm posting another reply showing what happens if you get it wrong... mainly, that you can't use the array's GetHashCode()
; the correct behaviour is that no warnings are printed when you run it... switch the comments to fix it:
using System;
using System.Collections.Generic;
using System.Linq;
static class Program
{
static void Main()
{
// first and second are logically equivalent
SimpleTableRow<int> first = new SimpleTableRow<int>(1, 2, 3, 4, 5, 6),
second = new SimpleTableRow<int>(1, 2, 3, 4, 5, 6);
if (first.Equals(second) && first.GetHashCode() != second.GetHashCode())
{ // proven Equals, but GetHashCode() disagrees
Console.WriteLine("We have a problem");
}
HashSet<SimpleTableRow<int>> set = new HashSet<SimpleTableRow<int>>();
set.Add(first);
set.Add(second);
// which confuses anything that uses hash algorithms
if (set.Count != 1) Console.WriteLine("Yup, very bad indeed");
}
}
class SimpleTableRow<T> : IEquatable<SimpleTableRow<T>>
{
public SimpleTableRow(int id, params T[] values) {
this.Id = id;
this.Values = values;
}
public int Id { get; private set; }
public T[] Values { get; private set; }
public override int GetHashCode() // wrong
{
return Id.GetHashCode() ^ Values.GetHashCode();
}
/*
public override int GetHashCode() // right
{
int hash = Id;
if (Values != null)
{
hash = (hash * 17) + Values.Length;
foreach (T t in Values)
{
hash *= 17;
if (t != null) hash = hash + t.GetHashCode();
}
}
return hash;
}
*/
public override bool Equals(object obj)
{
return Equals(obj as SimpleTableRow<T>);
}
public bool Equals(SimpleTableRow<T> other)
{
// Check for null
if (ReferenceEquals(other, null))
return false;
// Check for same reference
if (ReferenceEquals(this, other))
return true;
// Check for same Id and same Values
return Id == other.Id && Values.SequenceEqual(other.Values);
}
}
这篇关于包含通用数组对象GetHash code覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!