【问题标题】:C# - Stackoverflow exception when adding to HashSet<T>C# - 添加到 HashSet<T> 时的 Stackoverflow 异常
【发布时间】:2017-08-28 13:01:24
【问题描述】:

我有一个名为 Team 的课程。

class Team
{
        public Team(string name)
        {
            this.Name = name;
            this.Wins = 0;
            this.Opponents = new HashSet<Team>();
        }

        public string Name { get; set; }
        public int Wins { get; set; }
        public HashSet<Team> Opponents { get; set; }
}

每当我尝试在另一个团队的 HashSet 中添加一个具有单个对手的现有团队时,我都会收到 Stackoverflow 异常,而该团队的对手数量为零 guestTeam.Opponents.Add(homeTeam);

这里的主队在 Opponents 中有一个对手,而 guestTeam.Opponents 仍然是空的。

它是一个小型测试应用。 Stacktrace 的帧数显示为 3。

任何想法为什么我会抛出这样的异常?

【问题讨论】:

  • 显示导致异常的代码。顺便说一句,如果你在 HashSet 中使用自定义类,你应该重写 Equals+GetHashCodemeaningfully 和/或实现 IEquatable&lt;Team&gt;
  • @TimSchmelter 不需要覆盖Equals+GetHashCode,如果您可以比较参考。
  • @TitianCernicova-Dragomir:是的,但由于 HashSet&lt;&gt; 甚至是此类中的公共属性,他应该知道如果他使用不同的实例,他仍然可以添加重复的团队(例如相同的名称)。这通常是不可取的。在这种情况下,这肯定是代码异味
  • @TimSchmelter 没错,他应该意识到这一点,但代码看起来很简单,我猜他没有使用多个实例。但你说得很好:)
  • @TitianCernicova-Dragomir:什么代码?它是一个公共属性,甚至其他程序集也可以使用它并添加具有相同名称的不同实例

标签: c# exception overflow hashset


【解决方案1】:

我承认,我无法重现错误。我个人可以正确实施

: IEquatable<Team>

然后:

        public bool Equals(Team other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return string.Equals(this.Name, other.Name) && Equals(this.Opponents, other.Opponents);
    }

    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((Team)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((this.Name != null ? this.Name.GetHashCode() : 0) * 397) ^ (this.Opponents != null ? this.Opponents.GetHashCode() : 0);
        }
    }

    public static bool operator ==(Team left, Team right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(Team left, Team right)
    {
        return !Equals(left, right);
    }

当然我无法复制,所以它只是被拍摄了。

【讨论】:

    猜你喜欢
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多