1

我正在做一个项目,需要有关自动递增 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 查询类的所有实例并获取最大的数字,然后相应地设置静态变量。

我确信有一种更优雅的方式来处理这个问题。

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

4

2 回答 2

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);
}
于 2013-08-21T10:21:38.013 回答
0

你可以:

private static long iCatID = DateTime.Utc.Ticks;

使用转换为long. 因此,在您的程序的任何运行中(如果您的用户没有更改时钟),所有新 ID 都将是 > 所有旧 ID。

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

另一种解决方案是简单地忘记Id并使用Guid.

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

于 2013-08-21T10:21:54.500 回答