C# - 跟踪序列化和反序列化之间的自动递增变量

时间:2013-08-21 10:15:25

标签: c# serialization static-variables auto-increment

我正在开发一个项目,需要有关自动递增ID字段的帮助。

就序列化而言,在对每个实例化类的实例化时自动递增的静态变量进行反序列化时,从上次序列化获取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查询类的所有实例并获取最大数字,然后相应地设置静态变量。
  3. 我确信有更优雅的方式来解决这个问题。

    任何帮助都会很棒,谢谢。

2 个答案:

答案 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):< / p>

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

答案 1 :(得分:0)

你可以:

private static long iCatID = DateTime.Utc.Ticks;

使用long转换的当前时间(UTC)启动计数器。因此,如果您的程序运行有点运气(如果您的用户没有更改时钟),则所有新ID都将是&gt;所有旧ID。

请注意,通过使用UTC,您可以抵抗夏令时/冬令时的变化。

另一种解决方案是忘记Id并使用Guid

您通过Guid.NewGuid()生成它,它将是唯一的。唯一的问题是你刚刚丢失了物品的订购。你不能简单地比较两个Guid并告诉“这是更新的,这是更老的”。你可以说它们是平等的/不同的。