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 にリセットされていました。 .

私が知りたいのは、シリアライゼーションとデシリアライゼーションの間で自動インクリメント変数を追跡する方法と、ベストプラクティスは何ですか?

私はおそらくそれを行う2つの方法を考えました:

  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;

に変換された現在時刻 (UTC) でカウンターを開始しますlong。したがって、少し運が良ければ (ユーザーが時計を変更していない場合)、プログラムを実行すると、新しい ID はすべて古い ID よりも大きくなります。

UTC を使用すると、夏時間/冬時間の変更に耐性があることに注意してください。

別の解決策は、単に忘れてId使用することGuidです。

あなたはそれを生成しGuid.NewGuid()、それはユニークになります。唯一の問題は、アイテムの注文を失ったことです。Guid2 つを単純に比較して、「これは新しい、これは古い」と判断することはできません。それらが等しい/異なることがわかります。

于 2013-08-21T10:21:54.500 に答える