简体   繁体   English

将Object.GetHashCode()转换为Guid

[英]Converting Object.GetHashCode() to Guid

I need to assign a guid to objects for managing state at app startup & shutdown It looks like i can store the lookup values in a dictionary using 我需要为应用程序启动和关闭时管理状态的对象分配一个guid看起来我可以使用字典将查找值存储在字典中

dictionary<int,Guid>.Add(instance.GetHashCode(), myGUID());

are there any potential issues to be aware of here ? 这里有什么潜在的问题需要注意吗?

NOTE 注意

This does NOT need to persist between execution runs, only the guid like so 这不需要在执行运行之间持续存在,只需要像这样的guid

  • create the object 创建对象
  • gethashcode(), associate with new or old guid gethashcode(),与新的或旧的guid相关联
  • before app terminate, gethashcode() and lookup guid to update() or insert() into persistence engine USING GUID 在应用程序终止之前,gethashcode()和查找guid以更新()或插入()到持久性引擎USING GUID

    only assumption is that the gethashcode() remains consistent while the process is running 唯一的假设是gethashcode()在进程运行时保持一致

    also gethashcode() is called on the same object type (derived from window) 在相同的对象类型(从窗口派生)上调用gethashcode()

Update 2 - here is the bigger picture 更新2 - 这是更大的图片

  • create a state machine to store info about WPF user controls (later ref as UC) between runs 创建一个状态机,以便在运行之间存储有关WPF用户控件(后来引用为UC)的信息
  • the types of user controls can change over time (added / removed) 用户控件的类型可以随时间变化(添加/删除)
  • in the very 1st run, there is no prior state, the user interacts with a subset of UC and modifies their state, which needs to recreated when the app restarts 在第一次运行中,没有先前状态,用户与U​​C的子集交互并修改其状态,需要在应用重启时重新创建
  • this state snapshot is taken when the app has a normal shutdown 当应用程序正常关闭时,将拍摄此状态快照
  • also there can be multiple instances of a UC type 也可以有多种UC类型的实例
  • at shutdown, each instance is assigned a guid and saved along with the type info and the state info 在关机时,每个实例都会分配一个guid,并与类型信息和状态信息一起保存
  • all these guids are also stored in a collection 所有这些guid也存储在一个集合中
  • at restart, for each guid, create object, store ref/guid, restore state per instance so the app looks exactly as before 在重新启动时,为每个guid,创建对象,存储ref / guid,恢复每个实例的状态,以便应用程序看起来与以前完全一样
  • the user may add or remove UC instances/types and otherwise interact with the system 用户可以添加或删除UC实例/类型,否则与系统交互
  • at shutdown, the state is saved again 在关机时,状态再次被保存
  • choices at this time are to remove / delete all prior state and insert new state info to the persistence layer (sql db) 此时的选择是删除/删除所有先前状态并将新状态信息插入持久层(sql db)
  • with observation/analysis over time, it turns out that a lot of instances remain consistent/static and do not change - so their state need not be deleted/inserted again as the state info is now quite large and stored over a non local db 随着时间的观察/分析,事实证明很多实例保持一致/静态并且不会改变 - 所以它们的状态不需要再次删除/插入,因为状态信息现在非常大并且存储在非本地数据库上
  • so only the change delta is persisted 所以只保留更改增量
  • to compute the delta, need to track reference lifetimes 要计算增量,需要跟踪参考生命周期
  • currently stored as List<WeakReference> at startup 当前在启动时存储为List<WeakReference>
  • on shutdown, iterate through this list and actual UC present on screen, add / update / delete keys accordingly 在关机时,遍历此列表并在屏幕上显示实际UC,相应地添加/更新/删除密钥
  • send delta over to persistence 将delta发送到持久性

Hope the above makes it clear. 希望上面说清楚。

So now the question is - why not just store the HashCode (of usercontrol only) instead of WeakReference and eliminate the test for null reference while iterating thru the list 所以现在的问题是 - 为什么不只是存储HashCode(仅用户控件)而不是WeakReference并在通过列表迭代时消除空引用的测试

update 3 - thanks all, going to use weakreference finally 更新3 - 谢谢所有,最后将使用弱引用

You appear to be assuming that a hash code will be unique. 您似乎假设哈希码是唯一的。 Hash codes don't work like that. 散列码不起作用。 See Eric Lippert's blog post on Guidelines and rules for GetHashCode for more details, but basically you should only ever make the assumptions which are guaranteed for well-behaving types - namely the if two objects have different hash codes, they're definitely unequal. 有关更多详细信息,请参阅Eric Lippert 关于GetHashCode指南和规则的博客文章,但基本上您应该只为保持良好行为的类型做出假设 - 即如果两个对象具有不同的哈希码,则它们肯定是不相等的。 If they have the same hash code, they may be equal, but may not be. 如果它们具有相同的哈希码,则它们可能相等,但可能不相同。

EDIT: As noted, you also shouldn't persist hash codes between execution runs. 编辑:如上所述,您也不应该在执行运行之间保留哈希码。 There's no guarantee they'll be stable in the face of restarts. 面对重启,无法保证他们会保持稳定。 It's not really clear exactly what you're doing, but it doesn't sound like a good idea. 目前还不是很清楚你正在做什么,但这听起来不是一个好主意。

EDIT: Okay, you've now noted that it won't be persistent, so that's a good start - but you still haven't dealt with the possibility of hash code collisions. 编辑:好的,你现在已经注意到它不会持久,所以这是一个好的开始 - 但你仍然没有处理哈希码冲突的可能性。 Why do you want to call GetHashCode() at all? 你为什么要调用GetHashCode() Why not just add the reference to the dictionary? 为什么不添加对字典的引用?

Use GetHashCode to balance a hash table . 使用GetHashCode来平衡哈希表 That's what it's for. 这就是它的用途。 Do not use it for some other purpose that it was not designed for; 不要将它用于其他非设计用途的目的; that's very dangerous. 那很危险

The quick and easy fix seems to be 快速简便的修复似乎是

var dict = new Dictionary<InstanceType, Guid>();
dict.Add(instance, myGUID());

Of course you need to implement InstanceType.Equals correctly if it isn't yet. 当然,如果还没有正确实现InstanceType.Equals。 (Or implement IEQuatable<InstanceType> ) (或实现IEQuatable<InstanceType>

Possible issues I can think of: 我能想到的可能问题:

  • Hash code collisions could give you duplicate dictionary keys 散列码冲突可以为您提供重复的字典键
  • Different object's hash algorithms could give you the same hash code for two functionally different objects; 不同对象的哈希算法可以为两个功能不同的对象提供相同的哈希码; you wouldn't know which object you're working with 你不会知道你正在使用哪个对象
  • This implementation is prone to ambiguity (as described above); 这种实现容易模糊(如上所述); you may need to store more information about your objects than just their hash codes. 您可能需要存储有关对象的更多信息,而不仅仅是它们的哈希码。

Note - Jon said this more elegantly ( see above ) 注 - Jon更优雅地说( 见上文

Since this is for WPF controls, why not just add the Guid as a dependency proptery? 由于这是针对WPF控件的,为什么不将Guid添加为依赖项预测呢? You seem to already be iterating through the user controls, in order to get their hash codes, so this would probably be a simpler method. 您似乎已经在迭代用户控件,以获取其哈希码,因此这可能是一个更简单的方法。

If you want to capture that a control was removed and which Guid it had, some manager object that subscribes to closing/removed events and just store the Guid and a few other details would be a good idea. 如果你想捕获一个控件被删除以及它有哪个Guid,那么订阅关闭/删除事件的一些管理器对象只是存储Guid和其他一些细节将是一个好主意。 Then you would also have an easier time to capture more details for analysis if you need. 然后,如果需要,您还可以更轻松地捕获更多详细信息以进行分析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM