为对象派生唯一字典键的最佳方法是什么?

RLH*_*RLH 3 .net c# dictionary

问题

我需要一种为对象字典生成键的方法.但是,我有一些要求使这有点困难.这是场景:

  1. Dictionary是一个引用类型对象的列表.
  2. 字典private在静态类中.
  3. 外部代码需要获取字典中特定对象的密钥,但绝不能访问字典中的对象或字典本身.
  4. 给定字典中的特定对象,密钥必须始终可重新计算/可导出.如果对象上的属性发生更改,则键不能更改.
  5. 相反,如果创建了一个可以评估为equal字典中另一个对象的新对象,则该键必须不同,因为它们是两个独立的对象.
  6. 此实现必须是线程安全的.

NON-SOLUTIONS

解决方案#1
所有.Net对象都包含一个名为的方法.GetHashCode(),该方法返回一个整数值.您可以将其用作密钥.

问题
不可能.MSDN国家:

两个相等的对象返回相等的哈希码.

这打破了req#5,我假设(但没有测试)req.#4.我希望有这样一个选项,如果它符合这些规则.

解决方案#2
将指向对象的指针转换int为a并将其用作键.

问题
这打破了req的本质.#3.传递指针并将它们用作键并不安全.

解决方案#3
将指向对象的指针转换为整数哈希值,并使用哈希作为键.

问题
虽然这没有违反任何规则,但我宁愿避免访问指针,因为这将涉及使用unsafe代码.如果必须的话,我不反对使用不安全的代码,但如果可能的话,我宁愿避免使用它.

结论

也许我的要求有点挑剔.必须有一些合理的方法从唯一对象派生密钥.有没有人经历过这样的场景并解决了这个难题?

Hen*_*man 8

1字典是ByRef对象的列表.

对象总是在.NET中"通过引用".这可能是误解的开始.参考平等是您需要/想要的.

3外部代码需要获取字典中特定对象的密钥,但绝不能访问字典中的对象或字典本身.

这是真正的问题.没有它,对对象本身的引用就会起作用.但是框架仍然提供了所有功能,现成的:

private Dictionary<object, MyClass> _myStore;

// add an item and return a key    
public object Add(MyClass item)
{
    object key = new object();
    _myStore.Add(key, item);
    return key;
}
Run Code Online (Sandbox Code Playgroud)

并满足req#4:

private Dictionary<object, MyClass> _itemForKey;    // was _myStore
private Dictionary<MyClass, object> _keyForItem;


// add an item and return a key    
public object Add(MyClass item)
{
    object key = new object();
    _itemForKey.Add(key, item);
    _keyForItem.Add(item, key);
    return key;
}

protected object DeriveKeyFromItem(MyClass item)
{
   return _keyForItem[item];
}
Run Code Online (Sandbox Code Playgroud)

注意:这些示例不是线程安全的(请求6),但这是要解决的标准功能.