在运行时唯一标识对象的选项?
我需要在运行时为对象附加一个唯一的标识符。该标识符在应用程序的持续时间内必须是唯一的。我计划在对象模型的基类中拥有一个私有成员变量来做到这一点。该变量将在对象初始化时设置,并且该值在对象的生命周期内保持不变。在应用程序的持续时间内,任何其他对象都不能具有相同的标识符。
当然,我可以使用 System.Guid,但是每个对象需要 128 位的存储空间,我希望消耗更少的资源。我尝试使用 Int32 并使用 System.Environment.TickCount 初始化它 属性,但我没有获得足够的分辨率,并且某些对象最终分配了相同的值。
TickCounter 的文档表示,TickCount 属性将在大约 29 天内滚动到负值,然后在另外 29 天后返回到零。我很乐意用更高的分辨率来换取更短的滚动时间。
我还有其他我不知道的选择吗?
I need to attach a unique identifier to objects at runtime. The identifier must be unique for the duration of the application. I plan to do this my having a private member variable in the base class of my object model. This variable will be set at object initialization and the value will remain constant for the life of the object. No other object can have the same identifier for the duration of the application.
I can, of course, use a System.Guid, but that costs a 128 bits of storage for each object and I would like to consume fewer resources. I tried using an Int32 and initializing it with the System.Environment.TickCount property, but I don't get enough resolution and some objects wind up having the same value assigned.
The documentation for the TickCounter says that the TickCount property will roll to negative after ~29 and then back to zero in another 29 days. I would happly trade more resolution for a shorter roll over time.
Do I have other options that I don't know about?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我建议使用整数值,并在分配时自动递增它。您可以使用 Interlocked.Increment 使此操作线程安全。
最有可能的是,32 位整数足以完成此任务。我会推荐类似的东西:
然后您可以在基类中使用它来分配新的唯一标识符。
I would recommend using an integer value, and auto-incrementing it on assignment. You could use Interlocked.Increment to make this operation thread safe.
Most likely, a 32bit integer will be large enough for this task. I would recommend something like:
You can then use that in your base class for assigning a new, unique identifier.
要为对象生成唯一的 ID,您可以使用我们方便地为您提供的名称恰当的 ObjectIDGenerator:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.objectidgenerator.aspx
请注意,作为注释点出来,对象 id 生成器保持对活动对象的引用,因此它仅适用于您知道无论如何都会在应用程序生命周期中生存的对象。如果你打算在更短暂的对象上使用这个东西,那么这不是一个好的解决方案。
如果需要,您可以构建自己的对象 ID 生成器来保留弱引用;不会那么困难。
To generate unique ids for objects you could use the aptly named ObjectIDGenerator that we conveniently provide for you:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.objectidgenerator.aspx
Note that, as the comment points out, the object id generator keeps a reference to the object alive, so it is only suitable for objects that you know are going to survive the life of the application anyway. If you intend to use this thing on more ephemeral objects then it is not a good solution.
You could build your own object ID generator that kept weak references if you wanted; it wouldn't be that difficult.
您是否需要标识符在所有对象中唯一或仅在特定类型内唯一?
您有几个选择:
Object.GetHashCode()
,这将为您提供一个漂亮(但不是100%)可靠的标识符。但请注意,(根据文档),这并不能保证是唯一的。然而,你击中重复的机会非常低。private static long lastObjectId
。在基本构造函数中,使用Interlocked.Increment(ref lasObjectId)
作为当前对象的值。Do you need the identifier to be unique across all objects or just within a specific type?
You have a couple of options:
Object.GetHashCode()
, this will give you a pretty (but not 100%) reliable identifier. Note, though, that (per the docs), this is not guaranteed to be unique. Your chances of hitting a duplicate, though, are pretty low.private static long lastObjectId
in your class. Within the base constructor, useInterlocked.Increment(ref lasObjectId)
as the value for the current object.如果唯一性只是为了应用程序的生命周期,那么您不能使用一个 32 位整数,初始化为零,然后随着每个对象分配而简单地递增吗?
无需担心 TickCount 或类似的问题。数字“2”在数字中是唯一的;如果您测试的只是相等,那么它与“1”和“3”的不同与与“1,203,718”的不同一样。
If the uniqueness is just for the life of the application, can't you use a 32-bit integer, initialized to zero, and then simply incremented with each object allocation?
There's no need to worry about TickCount or anything like that. The number "2" is unique among numbers; it's as different from "1" and "3" as it is from "1,203,718" if all you're testing for is equality.