简体   繁体   中英

Reset an auto-increment counter in object

I have a class containing an auto-increment counter like this:

class MyClass
{
    private static object sync = new object();
    private static int globalCount;
    private int idUnique;

    public MyClass()
    {
        lock(sync)
        {
            idUnique = ++globalCount; 
        }
    }
}

The problem is, in my app, when the user deletes an instance of MyClass, I'd like it to reset the counter and recalculate the counter for the remaining instances of MyClass.

For example:

MyClass a has IdUnique of 1  
MyClass b has IdUnique of 2  
MyClass c has IdUnique of 3  
MyClass d has IdUnique of 4

The user deletes b & c so the app updates the remaining instances so a has a IdUnique of 1 and d has a IdUnique of 2 .

Such a thing is more of a property of a collection of your objects than anything else.

If you were to organise your object instances into an array-type structure, then you could use the position of your object in that array as the unique identifier.

(When deleting an item, you delete it from the array causing all elements to the "right" of it to shift back by one, if you get my meaning.)

I don't like it very much... (to be clear: the code should work correctly, but I don't LIKE it). Note that Delete() is a O(n) operation now... And it could be converted in a Dispose() (plus the automatic call from the finalizer).

Some test code:

var insts = new[] { new MyClass(), new MyClass(), new MyClass(), new MyClass() };
Console.WriteLine(string.Join(", ", (object[])insts));
insts[1].Delete();
Console.WriteLine(string.Join(", ", (object[])insts));
insts[3].Delete();
Console.WriteLine(string.Join(", ", (object[])insts));
insts[0].Delete();
Console.WriteLine(string.Join(", ", (object[])insts));
insts[2].Delete();
Console.WriteLine(string.Join(", ", (object[])insts));

and the class... Note that I'm keeping a static SortedSet<> that contains all the instances. I'm even creating an "ordering" of MyClass (the IComparable<MyClass> )

class MyClass : IComparable<MyClass> {
    public static SortedSet<MyClass> Instances = new SortedSet<MyClass>();
    private static object sync = new object();
    private int idUnique;
    private int originalIdUnique;

    public MyClass() {
        lock (sync) {
            idUnique = Instances.Count > 0 ? Instances.Max.idUnique + 1 : 1;
            originalIdUnique = idUnique;
            Instances.Add(this);
        }
    }

    // It could be a Dispose()!
    public void Delete() {
        if (idUnique == int.MinValue) {
            return;
        }

        lock (sync) {
            Instances.Remove(this);

            if (Instances.Count > 0 && this.idUnique < Instances.Max.idUnique) {
                var instances = Instances.GetViewBetween(this, Instances.Max);

                foreach (var instance in instances) {
                    instance.idUnique--;
                }
            }

            idUnique = int.MinValue;
        }
    }

    public override string ToString() {
        return string.Format("Id: {0} (OriginalId: {1})", idUnique, originalIdUnique);
    }

    #region IComparable<MyClass> Members

    public int CompareTo(MyClass other) {
        return idUnique.CompareTo(other.idUnique);
    }

    #endregion
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM