Dictionary <tkey,tvalue =“”>覆盖Indexer和FindEntry </tkey,>

时间:2012-12-27 17:53:15

标签: c# dictionary mono

为了优化我的代码,我正在尝试创建自己的Indexer和我自己的FindEntry函数版本 - 这样我就可以在{{1}中执行以下操作类似于:

Dictionary

这很有用,因为我的字典键是一个结构 - 但有时候我有哈希码而不是密钥。

我正在寻找object IDictionary.this[int key] { get { int num = this.FindEntry(key); if (num >= 0) { return this.entries[num].value; } return null; } set { Dictionary<TKey, TValue>.VerifyValueType(value); this [key] = (TValue)((object)value); } } private int FindEntry (int key) { if (this.buckets != null) { int num = key & 2147483647; for (int i = this.buckets[num % this.buckets.Length]; i >= 0; i = this.entries[i].next) { if (this.entries[i].hashCode == num && this.comparer.Equals(this.entries[i].key, key)) { return i; } } } return -1; } 重写以外的解决方案<{1}} - 但我怀疑这可能是唯一的方法,因为变量Dictionary<TKey, TValue>在它内部是私人的。

以下是我的代码的基本示例,以帮助展示我正在尝试完成的任务。

System

entries

在上面的struct SuperKey : IEquatable<SuperKey> { public int Id; public int Environment; public override int GetHashCode() { return this.Id; } public override bool Equals(object other) { return other is SuperKey ? Equals((SuperKey)other) : false; } public bool Equals(SuperKey other) { return this.Id == other.Id && this.Environment == other.Environment; } } 方法中,请注意以下一行:

  

class Example { Dictionary<SuperKey, Player> players; void MyFunction() { SuperKey sk = new SuperKey(36, 1); Player p1 = new Player(); players.Add(sk, p1); } void ReceiveEventForPlayer(int id, PlayerEventName name) { ReceiveEventForPlayer(id, 0, name); } void ReceiveEventForPlayer(int id, int environment, PlayerEventName name) { Player p = players[new SuperKey(id, 1)]; } }

我更愿意使用:

  

ReceiveEventForPlayer

但是这不起作用......实际上 理想的是能够使用 语法。

2 个答案:

答案 0 :(得分:1)

您对可能无效的Dictionary<TKey, TValue>的实施做了很多假设。例如:

  • 您假设通过开放寻址解决了冲突。它们可以通过重新散列或链接来轻松解决。
  • 您假设通过将返回的哈希码除以桶的数量来计算存储区位置。还有其他可能性。
  • 即使这两个假设证明是正确的,您也可以假设实施将来不会改变,并使之前的假设无效。

您还假设您可以访问基类的内部数据结构,这是不可能的。据我所知,buckets类的受保护接口中没有Dictionary数组。

从您发布的内容来看,似乎您保存的唯一执行时间(如果您的假设是正确的)将是计算每个项目的哈希码所花费的时间。通过在创建项目时(即在构造函数中)计算项目的哈希码并缓存它,可以轻松解决这个问题。那么,您的GetHashCode方法只是return this.cachedHashCode;

当然,假设您放置在字典中的项目是不可变的。或者,至少,用于确定相等性的任何字段都是不可变的。

最后,您确定Dictionary是您计划绩效的限制因素吗?如果没有,也许你的优化工作会更好地花在其他地方。

答案 1 :(得分:0)

Jim和Jon是正确的,我认为解决问题的方法很简单:

只需更改为GetHashCode以连接db number,“ - ”和用户编号,然后在该字符串上调用基本GetHashCode。

通过这种方式,您无需在生产和调试中更改实现。