2011-01-31 45 views
5

我需要在運行時將唯一標識符附加到對象。標識符在應用程序的持續時間內必須是唯一的。我打算這樣做我的對象模型的基類中有一個私有成員變量。該變量將在對象初始化時設置,並且該值將在對象的整個生命週期內保持不變。其他對象在應用程序的持續時間內不能有相同的標識符。在運行時唯一標識對象的選項?

我當然可以使用System.Guid,但每個對象的成本爲128位,我想消耗更少的資源。我嘗試使用Int32並使用System.Environment.TickCount屬性對它進行初始化,但我沒有獲得足夠的分辨率,並且某些對象被分配了相同的值。

TickCounter的文檔說TickCount屬性將在〜29之後滾動到負數,然後在另一個29天內回到零。我會很樂意交換更多的分辨率,以縮短更長的時間。

我還有其他的選擇我不知道嗎?

+3

什麼資源你害怕使用GUID會消耗過多?這句話聽起來有點像不成熟的優化。我會從一個使用GUID的解決方案開始,只有在遇到具體的性能瓶頸時才重新考慮它。 – 2011-01-31 18:02:37

+0

我一直在想這個問題。謝謝大家讓我走上正軌。 – 2011-01-31 18:43:07

回答

13

我建議使用整數值,並在賦值時自動遞增它。您可以使用Interlocked.Increment使此操作線程安全。

最有可能的是,一個32位整數對於這項任務來說足夠大。我會推薦類似於:

private static newObjectId = int.MinValue; 

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

然後,您可以在您的基類中使用它來分配新的唯一標識符。

+0

擊敗我。 :) – 2011-01-31 18:08:23

+0

好的。你會把它放在你需要該ID的類中,然後在構造函數中執行賦值。 – KeithS 2011-01-31 18:24:26

2

如果唯一性僅適用於應用程序的生命週期,那麼您不能使用32位整數,初始化爲零,然後只需增加每個對象分配?

有沒有必要擔心TickCount或類似的東西。數字「2」在數字中是唯一的;它與「1」和「3」不同,因爲它是從「1,203,718」,如果你所測試的是平等。

+1

關於你最後一句話的一些事情讓我想起聖手榴彈的指示 – 2011-01-31 18:02:30

3

您是否需要標識符在所有對象中是唯一的還是隻在特定類型中?

你有兩個選擇:

  1. 如果不重寫Object.GetHashCode(),這會給你一個漂亮(但不是100%),可靠的標識符。請注意,雖然(按照文檔),這不是保證是唯一的。但是,重複打印的機率非常低。
  2. 如果您是(或需要100%),最簡單的解決方案是在班級中使用private static long lastObjectId。在基礎構造函數內,使用Interlocked.Increment(ref lasObjectId)作爲當前對象的值。
  3. 如果您需要標識符在對象之間是唯一的,則可以執行類似於2的操作,但您必須使用中心類來管理這些標識。
8

要生成你可以使用適當命名的ObjectIDGenerator對象的唯一ID,我們方便地爲您提供:

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

注意的是,作爲評論指出,對象ID生成保持對活着的對象的引用,所以它只適用於你知道的對象將在應用程序的生命中倖存下來。如果你打算在更短暫的對象上使用這個東西,那麼它不是一個好的解決方案。

你可以建立你自己的對象ID生成器,如果你想要的話可​​以保留弱引用;它不會那麼困難。