gpt4 book ai didi

c# - 无法从 Iesi.Collections.Generic ISet 中删除项目

转载 作者:太空宇宙 更新时间:2023-11-03 10:47:29 24 4
gpt4 key购买 nike

我有一个类型的集合:
Iesi.Collections.Generic

public ISet<ItemBinding> ItemBindings { get; set; }

ItemBindingDomain.Model

我以这种方式初始化集合:

ItemBindings = new HashedSet<ItemBinding>();

然后我用成员填充集合。

当我想从这个集合中删除一个项目时,我无法删除它。

private void OnRemove(ItemBinding itemToRemove) {
ItemBindings.Remove(itemToRemove);
}

即使 itemToRemove 也与集合中的项目具有相同的 hashCode

我还尝试在集合中找到该项目,将其保存在一个变量中,然后将其删除:

private void OnRemove(ItemBinding itemToRemove) {
var foundItem = ItemBindings.Single( x => x.Id == itemToRemove.Id); // always if found
ItemBindings.Remove(foundItem);
}

但这行不通。

一个可行的解决方法是:

private void OnRemove(ItemBinding itemToRemove) {
var backUpItems = new List<ItemBinding>(ItemBindings);
backUpItems.Remove(itemToRemove);

ItemBindings.Clear();
ItemBindings.AddAll(backUpItems);
}

但这是一个肮脏的解决方法。我正在尝试以一种优雅的方式执行这个简单的删除:)。

改变类型

如果我从 IList 中的 ISet 更改类型,它工作正常。

public IList<ItemBinding> ItemBindings { get; set; }
ItemBindings = new List<ItemBinding>();

当我想从这个集合中删除一个项目时,它被删除了。

private void OnRemove(ItemBinding itemToRemove) {
ItemBindings.Remove(itemToRemove);
}

我无法从 ISet 中删除项目的方式中缺少什么......?

感谢您的建议和解决方案。

最佳答案

这是一个非常简单的问题。只需下载 dotPeek 1.2 并启动符号服务器,然后您就可以检查 ISet.Remove() 的实际实现,看看为什么它很挑剔。正如@HansPassant 所说,这可能是 GetHashCode() 的情况,或者 HashedSet 的实际实现

至于我的推测;看一下 DictionarySet(HashedSet 的基类):

https://www.symbolsource.org/Public/Metadata/Default/Project/NHibernate/3.0.0.Alpha2/Release/All/Iesi.Collections/Iesi.Collections/Generic/DictionarySet.cs

如您所见,Remove() 使用 Contains() 实际测试它是否应该删除元素。 Contains() 是做什么的?基本上它是 Dictionary.Contains() 的包装器

http://msdn.microsoft.com/en-us/library/ms182358(v=vs.80).aspx

GetHashCode returns a value based on the current instance that is suited for hashing algorithms and data structures such as a hash table. Two objects that are the same type and are equal must return the same hash code to ensure that instances of System.Collections.HashTable and System.Collections.Generic.Dictionary work correctly.

请注意,重要的是:

1) 您的 GetHashCode() 不能更改。这意味着 GetHashCode() 使用的所有字段都不能更改。一旦您将元素插入到 Dictionary 中,它的 GetHashCode() 就会被调用并将其放入特定的桶中。当您以后有不同的 GetHashCode() 时,您将无法恢复它。在 GetHashCode() 通过后,将调用您的 Equals 方法。确保您的字段是不可变的。

相关词典来源:

private int FindEntry(TKey key)
{
if ((object) key == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
if (this.buckets != null)
{
int num = this.comparer.GetHashCode(key) & int.MaxValue;
for (int index = this.buckets[num % this.buckets.Length]; index >= 0; index = this.entries[index].next)
{
if (this.entries[index].hashCode == num && this.comparer.Equals(this.entries[index].key, key))
return index;
}
}
return -1;
}

查看此线程如何覆盖 Equals() 和 GetHashCode():

Why is it important to override GetHashCode when Equals method is overridden?

请注意@Albic 在该线程中的回答。

关于c# - 无法从 Iesi.Collections.Generic ISet<T> 中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22858343/

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