gpt4 book ai didi

c# - IEquatable 的类实现,用作字典中的键

转载 作者:太空狗 更新时间:2023-10-29 21:33:56 26 4
gpt4 key购买 nike

我有一个包含两个字符串和一个枚举的类。我正在尝试使用此类的实例作为字典中的键。不幸的是,我似乎没有正确实现 IEquatable。这是我的做法:

public enum CoinSide
{
Heads,
Tails
}

public class CoinDetails : IComparable, IEquatable<CoinDetails>
{
private string denomination;
private string design;
private CoinSide side;

//...

public int GetHashCode(CoinDetails obj)
{
return string.Concat(obj.Denomination, obj.Design, obj.Side.ToString()).GetHashCode();
}

public bool Equals(CoinDetails other)
{
return (this.Denomination == other.Denomination && this.Design == other.Design && this.Side == other.Side);
}
}

但是,我似乎仍然无法在字典中查找项目。此外,以下测试失败:

    [TestMethod]
public void CoinDetailsHashCode()
{
CoinDetails a = new CoinDetails("1POUND", "1997", CoinSide.Heads);
CoinDetails b = new CoinDetails("1POUND", "1997", CoinSide.Heads);
Assert.AreEqual(a.GetHashCode(), b.GetHashCode());
}

[TestMethod]
public void CoinDetailsCompareForEquality()
{
CoinDetails a = new CoinDetails("1POUND", "1997", CoinSide.Heads);
CoinDetails b = new CoinDetails("1POUND", "1997", CoinSide.Heads);
Assert.AreEqual<CoinDetails>(a, b);
}

有人能指出我哪里出错了吗?我确定我遗漏了一些相当简单的东西,但我不确定是什么。

最佳答案

您的类(class)必须覆盖 EqualsGetHashCode :

public class CoinDetails 
{
private string Denomination;
private string Design;
private CoinSide Side;

public override bool Equals(object obj)
{
CoinDetails c2 = obj as CoinDetails;
if (c2 == null)
return false;
return Denomination == c2.Denomination && Design == c2.Design;
}

public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + (Denomination ?? "").GetHashCode();
hash = hash * 23 + (Design ?? "").GetHashCode();
return hash;
}
}
}

请注意,我还改进了您的 GetHashCode算法根据:What is the best algorithm for an overridden System.Object.GetHashCode?

您还可以传递自定义 IEqualityComparer<CoinDetail>字典:

public class CoinComparer : IEqualityComparer<CoinDetails>
{
public bool Equals(CoinDetails x, CoinDetails y)
{
if (x == null || y == null) return false;
if(object.ReferenceEquals(x, y)) return true;
return x.Denomination == y.Denomination && x.Design == y.Design;
}

public int GetHashCode(CoinDetails obj)
{
unchecked
{
int hash = 17;
hash = hash * 23 + (obj.Denomination ?? "").GetHashCode();
hash = hash * 23 + (obj.Design ?? "").GetHashCode();
return hash;
}
}
}

现在这可以工作并且不需要 CoinDetails覆盖 Equals + GetHashCode :

var dict = new Dictionary<CoinDetails, string>(new CoinComparer());
dict.Add(new CoinDetails("1POUND", "1997"), "");
dict.Add(new CoinDetails("1POUND", "1997"), ""); // FAIL!!!!

关于c# - IEquatable 的类实现,用作字典中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22175336/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com