C#hashtable包含返回false,当我知道它有一个带有键的条目时
通过调试,我可以看到m_foodTasks中有一个蚂蚁,其值完全相同。所以我假设它比较了参考地址…(我说的对吗?) 我如何通过价值进行比较 阅读答案后编辑: 太多的信息。。。 我会花一些时间来研究这些,但这里是蚂蚁班已经拥有的(我不能说这些东西是什么):C#hashtable包含返回false,当我知道它有一个带有键的条目时,c#,hashtable,C#,Hashtable,通过调试,我可以看到m_foodTasks中有一个蚂蚁,其值完全相同。所以我假设它比较了参考地址…(我说的对吗?) 我如何通过价值进行比较 阅读答案后编辑: 太多的信息。。。 我会花一些时间来研究这些,但这里是蚂蚁班已经拥有的(我不能说这些东西是什么): 公共类位置:IEquatable{ /// ///获取此位置的行。 /// 公共int行{get;私有集;} /// ///获取此位置的列。 /// 公共int列{get;私有集;} 公共位置(整数行,整数列){ this.Row=行;
公共类位置:IEquatable{
///
///获取此位置的行。
///
公共int行{get;私有集;}
///
///获取此位置的列。
///
公共int列{get;私有集;}
公共位置(整数行,整数列){
this.Row=行;
this.Col=Col;
}
公共覆盖布尔等于(对象对象对象){
if(ReferenceEquals(null,obj))
返回false;
if(ReferenceEquals(this,obj))
返回true;
if(obj.GetType()!=typeof(位置))
返回false;
返回等于((位置)obj);
}
公共布尔等于(其他位置){
if(ReferenceEquals(null,其他))
返回false;
if(ReferenceEquals(this,other))
返回true;
返回other.Row==this.Row&&other.Col==this.Col;
}
公共覆盖int GetHashCode()
{
未经检查{
返回(this.Row*397)^this.Col;
}
}
}
公共类团队位置:位置,可满足{
///
///得到这只蚂蚁的团队。
///
公共int团队{get;private set;}
公共团队位置(国际行、国际列、国际团队):基本(国际行、国际列){
这个团队=团队;
}
公共布尔等于(团队位置其他){
返回base.Equals(其他)和&other.Team==团队;
}
公共覆盖int GetHashCode()
{
未经检查{
int result=this.Col;
结果=(结果*397)^this.Row;
结果=(结果*397)^this.Team;
返回结果;
}
}
}
公共类Ant:TeamLocation,IEquatable{
公共蚂蚁(国际行,国际列,国际队):基地(国际行,国际列,国际队){
}
公共布尔等于(其他蚂蚁){
返回基数。等于(其他);
}
}
检查相等性时,需要重写GetHashCode()方法
public class Location : IEquatable<Location> {
/// <summary>
/// Gets the row of this location.
/// </summary>
public int Row { get; private set; }
/// <summary>
/// Gets the column of this location.
/// </summary>
public int Col { get; private set; }
public Location (int row, int col) {
this.Row = row;
this.Col = col;
}
public override bool Equals (object obj) {
if (ReferenceEquals (null, obj))
return false;
if (ReferenceEquals (this, obj))
return true;
if (obj.GetType() != typeof (Location))
return false;
return Equals ((Location) obj);
}
public bool Equals (Location other) {
if (ReferenceEquals (null, other))
return false;
if (ReferenceEquals (this, other))
return true;
return other.Row == this.Row && other.Col == this.Col;
}
public override int GetHashCode()
{
unchecked {
return (this.Row * 397) ^ this.Col;
}
}
}
public class TeamLocation : Location, IEquatable<TeamLocation> {
/// <summary>
/// Gets the team of this ant.
/// </summary>
public int Team { get; private set; }
public TeamLocation (int row, int col, int team) : base (row, col) {
this.Team = team;
}
public bool Equals(TeamLocation other) {
return base.Equals (other) && other.Team == Team;
}
public override int GetHashCode()
{
unchecked {
int result = this.Col;
result = (result * 397) ^ this.Row;
result = (result * 397) ^ this.Team;
return result;
}
}
}
public class Ant : TeamLocation, IEquatable<Ant> {
public Ant (int row, int col, int team) : base (row, col, team) {
}
public bool Equals (Ant other) {
return base.Equals (other);
}
}
公共类Ant:IEquatable
{
私有字符串_someField;
公共蚂蚁(字符串字段)
{
这个。_someField=someField;
}
#区域平等成员
公共布尔等于(其他蚂蚁)
{
if(ReferenceEquals(null,其他))
{
返回false;
}
if(ReferenceEquals(this,other))
{
返回true;
}
返回字符串.Equals(_someField,other._someField);
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))
{
返回false;
}
if(ReferenceEquals(this,obj))
{
返回true;
}
如果(obj.GetType()!=this.GetType())
{
返回false;
}
返回等于((Ant)obj);
}
公共覆盖int GetHashCode()
{
返回(_someField!=null?_someField.GetHashCode():0);
}
#端区
}
您可以选择创建一个IEqualityComparer类来为您进行比较
public class Ant : IEquatable<Ant>
{
private string _someField;
public Ant(string someField)
{
this._someField = someField;
}
#region Equality members
public bool Equals(Ant other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return string.Equals(_someField, other._someField);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != this.GetType())
{
return false;
}
return Equals((Ant) obj);
}
public override int GetHashCode()
{
return (_someField != null ? _someField.GetHashCode() : 0);
}
#endregion
}
私有密封类SomeFieldEqualityComparer:IEqualityComparer
{
公共布尔等于(Ant x,Ant y)
{
if(ReferenceEquals(x,y))
{
返回true;
}
if(ReferenceEquals(x,null))
{
返回false;
}
if(ReferenceEquals(y,null))
{
返回false;
}
如果(x.GetType()!=y.GetType())
{
返回false;
}
返回字符串.Equals(x.\u someField,y.\u someField);
}
公共int GetHashCode(Ant obj)
{
返回(obj.\u someField!=null?obj.\u someField.GetHashCode():0);
}
}
您需要正确实现GetHash和Equals,以使类在搜索/字典中表现为“比较值”,而不是“比较引用”
另一个(可能更好的选择)是在创建字典时提供
在文章中可以找到示例,这里是压缩版本:
private sealed class SomeFieldEqualityComparer : IEqualityComparer<Ant>
{
public bool Equals(Ant x, Ant y)
{
if (ReferenceEquals(x, y))
{
return true;
}
if (ReferenceEquals(x, null))
{
return false;
}
if (ReferenceEquals(y, null))
{
return false;
}
if (x.GetType() != y.GetType())
{
return false;
}
return string.Equals(x._someField, y._someField);
}
public int GetHashCode(Ant obj)
{
return (obj._someField != null ? obj._someField.GetHashCode() : 0);
}
}
字典框=
新字典(new BoxEqualityComparer());
类别BoxEqualityComparer:IEqualityComparer
{
公共布尔等于(框b1、框b2)
{
返回b1.高度==b2.高度;
}
公共整数GetHashCode(框bx)
{
返回bx.Height.GetHashCode();
}
}
Ant类不是我的,但我可以看到它已经覆盖了一些Equals和GetHashCode方法,它们也是从IEquatable派生的,我没有得到任何这些东西..没有办法简单地让它比较该死的键值?听起来很简单,不是吗?@Icebone1000您是否已检查以确保GetHashCode
为您认为“相等”的两项返回相同的值。如果它们不一样,那么它们在字典中就不平等了。使用GetHashCode跳过这些限制的原因是,您不需要将正在搜索的值与所有键值进行比较。您只需要将它与具有相同哈希代码(应该是很小的一部分)的值进行比较,这将使它更加高效。如果您希望简单而不是效率,请使用不同的数据结构。
private sealed class SomeFieldEqualityComparer : IEqualityComparer<Ant>
{
public bool Equals(Ant x, Ant y)
{
if (ReferenceEquals(x, y))
{
return true;
}
if (ReferenceEquals(x, null))
{
return false;
}
if (ReferenceEquals(y, null))
{
return false;
}
if (x.GetType() != y.GetType())
{
return false;
}
return string.Equals(x._someField, y._someField);
}
public int GetHashCode(Ant obj)
{
return (obj._someField != null ? obj._someField.GetHashCode() : 0);
}
}
Dictionary<Box, String> boxes =
new Dictionary<Box, string>(new BoxEqualityComparer());
class BoxEqualityComparer : IEqualityComparer<Box>
{
public bool Equals(Box b1, Box b2)
{
return b1.Height == b2.Height;
}
public int GetHashCode(Box bx)
{
return bx.Height.GetHashCode();
}
}