如果值是对象并且这些对象的属性是键,是否有比字典更好的数据结构?
我有一个 Dictionary
,其中 int
是 obj
的属性。有没有更好的数据结构呢?我觉得使用属性作为钥匙是多余的。
此 Dictionary
是容器类中的一个字段,允许根据 int
id 数字对 obj
值进行随机索引。容器类中的简化(无异常处理)索引器如下所示:
obj this[int id]
{
get{ return this.myDictionary[id];}
}
其中 myDictionary
是前面提到的保存对象的 Dictionary
。
这可能是快速随机访问的典型方式,但我想获得第二意见。
I have a Dictionary<int, object>
where the int
is a property of obj
. Is there a better data structure for this? I feel like using a property as the key is redundant.
This Dictionary<int, obj>
is a field in a container class that allows for random indexing into the obj
values based on an int
id number. The simplified (no exception handling) indexer in the container class would look like:
obj this[int id]
{
get{ return this.myDictionary[id];}
}
where myDictionary
is the aforementioned Dictionary<int, obj>
holding the objects.
This may be the typical way of quick random access but I wanted to get second opinions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
框架中没有具体的类可以执行此操作。不过有一个抽象的,KeyedCollection。您必须从该类派生您自己的类并实现 GetKeyForItem() 方法。这非常简单,只需返回您想要索引的属性的值即可。
这就是您需要做的全部,但请密切关注 ChangeItemKey()。当用作键的属性更改值时,您必须执行一些有意义的操作。如果您确保该属性是不可变的(只有一个 getter),那么就很容易了。但如果你不这样做,那就很尴尬了,对象本身现在需要知道它存储在你的集合中。如果您不采取任何措施(调用 ChangeItemKey),该对象就会在集合中丢失,您将无法找回它。非常接近泄漏。
请注意 Dictionary<> 是如何显示的通过分别指定键值和对象来回避这个问题。您可能仍然无法找回该对象,但至少它不会因设计而丢失。
There's no concrete class in the framework that does this. There's an abstract one though, KeyedCollection. You'll have to derive your own class from that one and implement the GetKeyForItem() method. That's pretty easy, just return the value of the property by which you want to index.
That's all you need to do, but do keep an eye on ChangeItemKey(). You have to do something meaningful when the property that you use as the key changes value. Easy enough if you ensure that the property is immutable (only has a getter). But quite awkward when you don't, the object itself now needs to have awareness of it being stored in your collection. If you don't do anything about it (calling ChangeItemKey), the object gets lost in the collection, you can't find it back. Pretty close to a leak.
Note how Dictionary<> side-steps this problem by specifying the key value and the object separately. You may still not be able to find the object back but at least it doesn't get lost by design.
有一个 KeyedCollection 类。
编辑:KeyedCollection 可以在内部使用字典,但对于这种特定场景,它的界面比原始字典更干净,因为您可以直接按值查找。诚然,我觉得它总体上不是很有用。
There is a KeyedCollection class.
EDIT: The KeyedCollection can use a dictionary internally, but it cleaner interface for this particular scenario than a raw dictionary since you can lookup by values directly. Admittedly I don't find it very useful in general.
如果工厂设置带来的额外开销不值得,您可以轻松实现自己的
KeyedCollection
。System.Collections.ObjectModel
中的原始KeyedCollection
内部是一个Dictionary
和一个List
code> 这意味着您可以在IList<>
和IDictionary<>
上定义操作。例如,您可以插入、按索引访问、按插入顺序遍历集合(所有这些IList<>
都很方便),同时您可以基于键进行快速查找(借助字典)。这意味着,当您添加或删除项目时,除了保存额外的List
所需的少量内存开销之外,还必须在两个基础集合上执行这些项目(但对象不会重复)像这样)。虽然添加速度不会受到太大影响(List>>
添加是 O(1)),删除速度受到一点影响。如果你不关心插入顺序和按索引访问:
我已经实现了
ICollection
使其更加符合标准 - 并且您还可以获得很好的集合初始值设定项语法! :)示例用法:
You can implement your own
KeyedCollection
trivially if the extra overhead that comes with the factory settings isn't worth it. The originalKeyedCollection
inSystem.Collections.ObjectModel
is internally aDictionary<TKey, TItem>
and aList<TItem>
which means you can have operations defined on bothIList<>
andIDictionary<>
. For e.g., you can insert, access by index, traverse collection in the inserted order (all whichIList<>
facilitates) and at the same time you can have quick lookups based on key (with the help of dictionary). This means that when you're adding or removing an item they have to be performed on both underlying collections, apart from the small memory overhead to hold the extraList<>
(but the objects are not duplicated as such). Though the addition speeds are not affected much (List<>
addition is O(1)), removal speed is affected a little.If you don't care about insertion order and accessing by index:
I have implemented
ICollection<TItem>
to make it more standard compliant - and also you get the nice collection initializer syntax! :)A sample usage:
C# 动态属性 帖子似乎表明使用字典是一种流行的选择。其他帖子建议使用 HashTable
字典与哈希表
C# dynamic properties post seems to show that using a Dictionary was a popular choice. The other posts suggest using a HashTable
Dictionary vs Hashtable