나는 다음과 같은 클래스가 :를 GetHashCode 휴식 코드
이 코드를 사용하는 경우와 ResourcePack의 인스턴스 멤버를 생성하면 더 이상 변하지 않는 단 하나의 장소가있다public class ResourcePack
{
private int m_pirates;
private int m_islands;
private int m_enemy_drones;
private int m_enemy_pirates;
public ResourcePack()
{
this.m_pirates = 0;
this.m_islands = 0;
this.m_enemy_drones = 0;
this.m_enemy_pirates = 0;
}
public ResourcePack(ResourcePack other)
{
this.m_pirates = other.m_pirates;
this.m_islands = other.m_islands;
this.m_enemy_drones = other.m_enemy_drones;
this.m_enemy_pirates = other.m_enemy_pirates;
}
public bool CanConcatinate(ResourcePack other)
{
if ((this.m_islands & other.m_islands) != 0)
{
return false;
}
if ((this.m_enemy_drones & other.m_enemy_drones) != 0)
{
return false;
}
if ((this.m_enemy_pirates & other.m_enemy_pirates) != 0)
{
return false;
}
return true;
}
internal void AddIsland(int island)
{
m_islands |= (1 << island);
}
internal void AddPirate(int pirate)
{
m_pirates |= (1 << pirate);
}
internal void AddEnemyDrone(int drone)
{
m_enemy_drones |= (1 << drone);
}
internal void AddEnemyPirates(int pirate)
{
m_enemy_pirates |= (1 << pirate);
}
public ResourcePack SemiConcatinate(ResourcePack other)
{
var ret = new ResourcePack();
ret.m_pirates = this.m_pirates | other.m_pirates;
ret.m_islands = this.m_islands | other.m_islands;
ret.m_enemy_drones = this.m_enemy_drones | other.m_enemy_drones;
ret.m_enemy_pirates = this.m_enemy_pirates | other.m_enemy_pirates;
return ret;
}
public override bool Equals(object value)
{
ResourcePack other = value as ResourcePack;
return !object.ReferenceEquals(null, other)
&& int.Equals(m_pirates, other.m_pirates)
&& int.Equals(m_islands, other.m_islands)
&& int.Equals(m_enemy_drones, other.m_enemy_drones)
&& int.Equals(m_enemy_pirates, other.m_enemy_pirates);
}
/*
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash = (hash * 16777619)^m_pirates.GetHashCode();
hash = (hash * 16777619)^m_islands.GetHashCode();
hash = (hash * 16777619)^m_enemy_drones.GetHashCode();
hash = (hash * 16777619)^m_enemy_pirates.GetHashCode();
return hash;
}
}*/
public static bool operator ==(ResourcePack a, ResourcePack b)
{
if (object.ReferenceEquals(a, b))
return true;
if (object.ReferenceEquals(null, a))
return false;
return a.Equals(b);
}
public static bool operator !=(ResourcePack a, ResourcePack b)
{
return !(a == b);
}
}
.
Dictionary<ResourcePack, T> current = new Dictionary<ResourcePack, T>(missions[0].Length);
// current[t1] = t2; where t1 is an instance of ResourcePack
내가 GetHashCode를 오버라이드 (override)하지 말아 때가 가정으로, 코드가 작동합니다 ResourcePack가로 사용되는 있는 유일한 방법은 사전의 핵심 지표이다. 재정의 할 때 (GetHashCode 주석 처리 해제) 코드가 동일하게 작동하지 않고 출력이 무작위로 보입니다.
제발 누군가 나에게 이런 행동을 설명해 주시겠습니까? 내 사용자 정의 GetHashCode가 충분하지 않습니까?
업데이트 나는 당신의 제안을 읽은 후 내 코드를 변경했습니다,하지만 여전히 GetHashCode이 (정도?) 값 고유의 반환하지 않는 것 같다.
새로운 코드 : 나는라는 영역을 제거하면
public sealed class ResourcePack
{
private readonly int m_pirates;
private readonly int m_islands;
private readonly int m_enemy_drones;
private readonly int m_enemy_pirates;
public ResourcePack(int pirates, int islands, int enemy_drones, int enemy_pirates)
{
this.m_pirates = pirates;
this.m_islands = islands;
this.m_enemy_drones = enemy_drones;
this.m_enemy_pirates = enemy_pirates;
}
public ResourcePack(ResourcePack other)
{
this.m_pirates = other.m_pirates;
this.m_islands = other.m_islands;
this.m_enemy_drones = other.m_enemy_drones;
this.m_enemy_pirates = other.m_enemy_pirates;
}
public bool CanConcatinate(ResourcePack other)
{
if ((this.m_islands & other.m_islands) != 0)
{
return false;
}
if ((this.m_enemy_drones & other.m_enemy_drones) != 0)
{
return false;
}
if ((this.m_enemy_pirates & other.m_enemy_pirates) != 0)
{
return false;
}
return true;
}
public ResourcePack SemiConcatinate(ResourcePack other)
{
return new ResourcePack(this.m_pirates | other.m_pirates,
this.m_islands | other.m_islands,
this.m_enemy_drones | other.m_enemy_drones,
this.m_enemy_pirates | other.m_enemy_pirates);
}
#region Hashing
public override bool Equals(object value)
{
ResourcePack other = value as ResourcePack;
return !object.ReferenceEquals(null, other)
&& int.Equals(m_pirates, other.m_pirates)
&& int.Equals(m_islands, other.m_islands)
&& int.Equals(m_enemy_drones, other.m_enemy_drones)
&& int.Equals(m_enemy_pirates, other.m_enemy_pirates);
}
public override int GetHashCode()
{
unchecked
{
int hash = (int)23;
hash = (hash * 17)^m_pirates.GetHashCode();
hash = (hash * 17)^m_islands.GetHashCode();
hash = (hash * 17)^m_enemy_drones.GetHashCode();
hash = (hash * 17)^m_enemy_pirates.GetHashCode();
return hash;
}
}
public static bool operator ==(ResourcePack a, ResourcePack b)
{
if (object.ReferenceEquals(a, b))
return true;
if (object.ReferenceEquals(null, a))
return false;
return a.Equals(b);
}
public static bool operator !=(ResourcePack a, ResourcePack b)
{
return !(a == b);
}
#endregion
}
"해싱"모든 것이 잘 작동합니다.
해시에 대한 유사한 알고리즘은 어디에서 찾을 수 있습니까? 필드 해시를 훨씬 단순하게 XOR하는 이유는 무엇입니까? –
@MarioVernari 이미 시도했지만 작동하지 않았고 코드는 여전히 다르게 동작했습니다. 코드를 손상시키지 않는 유일한 방법은 내부 GetHashCode입니다. – user3601822
'GetHashCode'는 읽기 전용 멤버에서만 사용해야합니다. 해시 코드는 사전에서 올바른 버킷을 찾는 데 사용됩니다. 메서드가 다른 결과를 반환하면 사전은 다른 버킷을 선택합니다. – CSharpie