gpt4 book ai didi

c# - HashSet.RemoveWhere() 和 GetHashCode()

转载 作者:太空狗 更新时间:2023-10-29 22:27:32 27 4
gpt4 key购买 nike

你好,

这是一个覆盖 GetHashCode 的简单类:

class OverridesGetHashCode
{
public string Text { get; set; }

public override int GetHashCode()
{
return (Text != null ? Text.GetHashCode() : 0);
}
// overriding Equals() doesn't change anything, so I'll leave it out for brevity
}

当我创建该类的实例时,将其添加到 HashSet,然后更改其 Text 属性,如下所示:

var hashset = new HashSet<OverridesGetHashCode>();
var oghc = new OverridesGetHashCode { Text = "1" };
hashset.Add(oghc);
oghc.Text = "2";

那么这行不通了:

var removedCount = hashset.RemoveWhere(c => ReferenceEquals(c, oghc));
// fails, nothing is removed
Assert.IsTrue(removedCount == 1);

这也不是:

// this line works, i.e. it does find a single item matching the predicate
var existing = hashset.Single(c => ReferenceEquals(c, oghc));
// but this fails; nothing is removed again
var removed = hashset.Remove(existing);
Assert.IsTrue(removed);

我猜它内部使用的散列是在插入项目时生成的,如果这是真的,它是hashset.Contains(oghc) 不起作用是可以理解的。我还猜想它通过哈希码查找项目,如果找到匹配项,它只会检查谓词,这可能就是第一次测试失败的原因(同样,我只是在这里猜测)。但是为什么最后一次测试失败了,我只是从哈希集中得到了那个对象?我是否遗漏了什么,这是从 HashSet 中删除某些内容的错误方法吗?

感谢您花时间阅读本文。

更新:为避免混淆,这里是 Equals():

protected bool Equals(OverridesGetHashCode other)
{
return string.Equals(Text, other.Text);
}

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

最佳答案

HashSet 中使用该对象时更改该对象的哈希码违反了 HashSet 的约定。

无法移除对象不是这里的问题。 您一开始就不允许更改哈希码。

让我引用自MSDN :

The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method. Note that this is true only for the current execution of an application, and that a different hash code can be returned if the application is run again.

他们讲述的故事略有不同,但本质是一样的。他们说,哈希码永远不会改变。实际上,只要确保没有人再使用旧的哈希码,就可以更改它。并不是说这是好的做法,但它确实有效。

关于c# - HashSet<T>.RemoveWhere() 和 GetHashCode(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11848558/

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