2013-08-21 31 views
1

我正在開發一個項目,需要關於自動遞增ID字段的幫助。C# - 跟蹤序列化和反序列化之間的自動增量變量

在序列化方面,當涉及到靜態變量的反序列化時,從每個實例化類的每個實例化的靜態變量的反序列化中獲取ID的最佳方式是什麼?

例如...

[Serializable] 
class Category 
{ 
    private static int iCatID = 0; 
    private int iCategoryID; 
    private string sCategory; 

    public Category(string _sCategory) 
    { 
     iCatID++; 
     iCategoryID = iCatID; 
     sCategory = _sCategory; 
    } 
} 

我學到了艱辛的道路,創造這一類的5層左右的實例後,我序列化,然後反序列化和預期iCatID拿起它離開的地方時,我開始創建該類的更多實例,但它當然重置爲0.

我想知道的是如何跟蹤序列化和反序列化之間的自動遞增變量以及什麼是最佳實踐?

我想到了兩種方法可能做到這一點:

  1. 當序列化類,靜態變量的值保存到一個全局設置,並再次獲得該值從設置靜態變量關於反序列化的全球背景。
  2. 反序列化類時,請使用linq查詢該類的所有實例並獲取最高編號,然後相應地設置靜態變量。

我相信有一個更優雅的方式來處理這個問題。

任何幫助將是偉大的,謝謝。

+0

問題變了嗎?我不記得'iCategoryID'是原始版本;無論哪種方式,你實際上並沒有在任何時候爲'iCategoryID'賦值......所以我們應該期望*值爲0,否? –

+0

這並不意味着在那裏。我現在拿出來了。謝謝:-) –

+0

其實對不起,它應該在那裏。我還添加了如何在構造函數中使用它。但我認爲這不會改變問題的基礎。對困惑感到抱歉。 –

回答

1

系列化約爲情況......如果你花了快照那麼它會被保存,即

static int nextCatID; 
private readonly int catID; 
private string category; 
... 
public Category(string category) 
{ 
    catID = Interlocked.Increment(ref nextCatID); 
    this.category = category 
} 

這裏catID是與單個實例的價值 - 將被序列化和反序列化;當然,它可能會導致重複:如果序列化項目1,然後將其反序列化5次,則會再添加5個「項目1」。

如果你想要的值是反序列化期間集,你也可以這樣做 - 只是標記字段作爲非系列:

static int nextCatID; 
[NonSerialized] 
private int catID; 

,並使用它設置在一個序列化後回調從構造相同的代碼(注意,因爲回調構造,您不能使用readonly):

[OnDeserialized()] 
private void OnDeserialized(StreamingContext context) 
{ 
    catID = Interlocked.Increment(ref nextCatID); 
} 
+0

這似乎是我正在尋找。明天我會給它一個破解,看看這個實現產生了什麼結果。非常感謝。 –

+0

唯一的問題是如果他使用Id來連接多個項目。 – xanatos

+0

@xanatos的確如此,這就是爲什麼我提出了兩種*不同的方法,這取決於意圖是否像序列化時那樣再現它們,或者意圖是在反序列化時爲所有對象賦予新的身份 –

0

,你可以:

private static long iCatID = DateTime.Utc.Ticks; 

開始與當前時間(UTC)轉換的long你的櫃檯。因此,在運行程序時(如果用戶沒有更改時鐘),所有新ID都將>所有舊ID。

請注意,通過使用UTC,您可以抵禦夏令時/冬令時的變化。

另一種解決方法是簡單地忘掉Id並使用Guid

您通過Guid.NewGuid()生成它,它將是唯一的。唯一的問題是你剛剛失去了項目的順序。你不能簡單地比較兩個Guid,並告訴「這是更新的,這是更舊的」。你可以說他們是平等/不同的。

+0

似乎是一個好主意,但有可能有一個用戶可以訪問序列化的文件,保存它,然後一個朋友在世界的另一邊訪問相同的文件,這取決於時區可能會導致問題。不管怎麼說,還是要謝謝你。 –

+0

@ShaneBatey如果他們的時鐘設置正確,那麼這不是問題,因爲世界時UTC時間是絕對的。這是我使用'DateTime.Utc'而不是'DateTime'的原因。 'DateTime.Utc'現在在紐約,倫敦,東京都是一樣的...... – xanatos

+0

啊,我明白了。一個有效的選項。謝謝! –