- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个类型的集合:
Iesi.Collections.Generic
public ISet<ItemBinding> ItemBindings { get; set; }
ItemBinding
是 Domain.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
的基类):
如您所见,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/
因为我使用了两个不同的通用集合命名空间(System.Collections.Generic 和 Iesi.Collections.Generic),所以我有冲突。在项目的其他部分,我同时使用 nun
.NET 4 ISet<> HashSet<> 可以替换 NHibernate Iesi.Collections ISet 、 HashSet 吗?我正在使用 CaSTLe 代理和 NHibernat
有人必须将列表分配给 ISet 吗?我该怎么做? 说我有课 class Foo { ISet Items { get; set; } } 现在,我想做以下事情: var foo = new Foo
我有 2 个由 NHibernate 处理的类:AssetGroup、AssetAssetGroup 有一个 ISet _assets 集合。AssetGroup 的构造函数会说 _assets =
我想要一个 ISet还有两个附加事件 ItemAdded和 ItemRemoved . 我考虑的一个选项是派生 MyHashSet来自 HashSet但自 Add和 Remove不是虚拟的,它需要使用
我正在将 Windows Smart Client 解决方案从 nHibernate 2.2 升级到 4.0。这也需要更新 Iesi.Collections (4.0.1.4000)。 在这一行: p
在构建类时,我想用 HashSet 动态初始化所有 ISet, 下面是我如何用 List 实现 IList var properties = GetType() .Ge
我有三个类,分别是 Broker、Instrument 和 BrokerInstrument。 using Iesi.Collections.Generic; public class Broker
我想知道在 C# 中是否有任何类似于集合的只读接口(interface)声明了一个 Contains 方法。我不想只实现 ISet 接口(interface),因为它有太多不必要的方法。 我的想法实现
public override ISet SetCellContents(string name) { HashSet list = graph.GetDependents(
.NET 4.0 引入了一个非泛型 IList,它公开了向 List 添加值的能力,而无需知道泛型类型。这很有用,因为它允许我编写如下方法: void CreateListFromBytes(IntP
在大多数 NHiberate 示例中,他们使用 ISET 而不是 IList。我知道两者之间的基本区别即 一个集合是唯一的。但是,我不确定为什么他们在延迟加载时使用 ISet 而不是 IList。 (
我有一个客户有一个联系人列表。这个列表是一个 ISet 集合。我无法对其进行 Linq 查询。你能帮我吗? 谢谢, public class Customer { public virtual
.NET Framework 正在添加 ISet与 4.0 版本的接口(interface)。在同一版本中,F# 被添加为一流语言。 F# 提供了不可变的 Set类。 对我来说,提供的不可变集将实现
我在标题中提到的映射中遇到了一些问题。以下是详细信息: class MyDomain { public Iesi.Collections.Generic.ISet MySomeTypes{ ge
我有以下方法: private string TickIfHeadingPresent(Dictionary> data, TKey key, TValue value) {
Hazelcast IMap 支持 map 条目的生存时间。IMap 有这个 like 的方法 我的问题是,Hazelcast ISet 和 IList 是否支持条目的生存时间? 我在文档中找不到IS
有一种方法接受类型为 List 的参数,我需要将它分配给类型为 ISet 的 someTestModel id . public void testM1(List testIds) { var
我知道我不能重载返回类型(我想我知道这一点)。 void F() { } bool F() { return true; } ..产生错误已经用相同的参数类型定义了一个名为“F”的成员 但是,我
请帮我解释以下行为: dynamic d = 1; ISet s = new HashSet(); s.Contains(d); 代码编译时没有错误/警告,但在最后一行出现以下异常: Unhandle
我是一名优秀的程序员,十分优秀!