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

时间:2011-01-31 17:54:59

标签: c# performancecounter

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

我当然可以使用System.Guid,但每个对象需要128位存储空间,而且我希望消耗更少的资源。我尝试使用Int32并使用System.Environment.TickCount属性对其进行初始化,但是我得不到足够的分辨率,并且某些对象最终会分配相同的值。

TickCounter的文档说TickCount属性将在~29之后滚动到负值,然后在另外29天内回到零。随着时间的推移,我会很乐意交换更多的分辨率。

我还有其他我不了解的选择吗?

4 个答案:

答案 0 :(得分:13)

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

最有可能的是,32位整数对于此任务来说足够大。我建议像:

private static newObjectId = int.MinValue;

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

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

答案 1 :(得分:9)

要为对象生成唯一ID,您可以使用我们为您方便地提供的恰当名称 ObjectIDGenerator

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.objectidgenerator.aspx

请注意,正如注释所指出的那样,对象id生成器保持对对象的引用,因此它仅适用于您知道将在应用程序的生命周期中存活的对象。如果你打算在更短暂的物体上使用这个东西,那么这不是一个好的解决方案。

如果需要,您可以构建自己的对象ID生成器,保留弱引用;这不会那么困难。

答案 2 :(得分:3)

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

您有几个选择:

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

答案 3 :(得分:2)

如果唯一性仅适用于应用程序的生命周期,那么您是否不能使用32位整数,初始化为零,然后只需按每个对象分配递增?

没有必要担心TickCount或类似的东西。数字“2”在数字中是唯一的;它与“1”和“3”不同,因为如果您所测试的是相等的话,那么它来自“1,203,718”。

相关问题