在运行时唯一标识对象的选项?

发布于 2024-10-15 18:25:16 字数 590 浏览 5 评论 0原文

我需要在运行时为对象附加一个唯一的标识符。该标识符在应用程序的持续时间内必须是唯一的。我计划在对象模型的基类中拥有一个私有成员变量来做到这一点。该变量将在对象初始化时设置,并且该值在对象的生命周期内保持不变。在应用程序的持续时间内,任何其他对象都不能具有相同的标识符。

当然,我可以使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

彩扇题诗 2024-10-22 18:25:16

我建议使用整数值,并在分配时自动递增它。您可以使用 Interlocked.Increment 使此操作线程安全。

最有可能的是,32 位整数足以完成此任务。我会推荐类似的东西:

private static newObjectId = int.MinValue;

private static int GetNextId()
{
    return Interlocked.Increment(ref newObjectId);
}

然后您可以在基类中使用它来分配新的唯一标识符。

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:

private static newObjectId = int.MinValue;

private static int GetNextId()
{
    return Interlocked.Increment(ref newObjectId);
}

You can then use that in your base class for assigning a new, unique identifier.

蓦然回首 2024-10-22 18:25:16

要为对象生成唯一的 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.

£冰雨忧蓝° 2024-10-22 18:25:16

您是否需要标识符在所有对象中唯一或仅在特定类型内唯一?

您有几个选择:

  1. 如果您没有重写Object.GetHashCode(),这将为您提供一个漂亮(但不是100%)可靠的标识符。但请注意,(根据文档),这并不能保证是唯一的。然而,你击中重复的机会非常低。
  2. 如果您是(或需要 100%),最简单的解决方案是在您的类中使用 private static long lastObjectId。在基本构造函数中,使用 Interlocked.Increment(ref lasObjectId) 作为当前对象的值。
  3. 如果您需要标识符在对象之间是唯一的,您可以执行类似于 2. 的操作,但您必须使用中心类来管理这些 ID。

Do you need the identifier to be unique across all objects or just within a specific type?

You have a couple of options:

  1. If you aren't overriding 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.
  2. If you are (or need 100%), the simplest solution would be to use a private static long lastObjectId in your class. Within the base constructor, use Interlocked.Increment(ref lasObjectId) as the value for the current object.
  3. If you need the identifier to be unique across objects, you can do something similar to 2., but you'll have to use a central class to manage these ID's.
回忆凄美了谁 2024-10-22 18:25:16

如果唯一性只是为了应用程序的生命周期,那么您不能使用一个 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文