C# 类自动递增 ID

标签 c# class identity auto-increment member

我正在用 C# 创建一个名为“Robot”的类,每个机器人都需要一个唯一的 ID 属性来赋予它们自己一个身份。

有没有办法为每个新类对象创建一个自动增量 ID?所以,如果我创建了 5 个新机器人,它们的 ID 分别为 1、2、3、4、5。如果我随后销毁机器人 2 并稍后创建一个新机器人,它的 ID 将为 2。如果我添加一个第 6 个它将具有 6 的 ID,依此类推。

谢谢。

最佳答案

创建静态实例变量,并使用Interlocked.Increment(ref nextId)在上面。

class Robot {
    static int nextId;
    public int RobotId {get; private set;}
    Robot() {
        RobotId = Interlocked.Increment(ref nextId);
    }
}

注 #1:使用 nextId++仅在非并发环境中有效; Interlocked.Increment即使您从多个线程分配机器人也能正常工作。

编辑 这不涉及重复使用机器人 ID。如果您需要重用,解决方案要复杂得多:您需要一个可重用 ID 列表,以及一个 ReaderWriterLockSlim 围绕访问该列表的代码。

class Robot : IDisposable {
    static private int nextId;
    static private ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
    static private IList<int> reuseIds = new List<int>();
    public int RobotId {get; private set;}
    Robot() {
        rwLock.EnterReadLock();
        try {
            if (reuseIds.Count == 0) {
                RobotId = Interlocked.Increment(ref nextId);
                return;
            }
        } finally {
            rwLock.ExitReadLock();
        }
        rwLock.EnterWriteLock();
        try {
            // Check the count again, because we've released and re-obtained the lock
            if (reuseIds.Count != 0) {
                RobotId = reuseIds[0];
                reuseIds.RemoveAt(0);
                return;
            }
            RobotId = Interlocked.Increment(ref nextId);
        } finally {
            rwLock.ExitWriteLock();
        }
    }
    void Dispose() {
        rwLock.EnterWriteLock();
        reuseIds.Add(RobotId);
        rwLock.ExitWriteLock();
    }
}

注意#2:如果您想在较大的 ID 之前重用较小的 ID(而不是像我编码的那样在稍后发布的 ID 之前重用较早发布的 ID),您可以替换 IList<int> SortedSet<int> 并围绕从集合中获取要重用的 ID 的部分进行一些调整。

关于C# 类自动递增 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9262221/

相关文章:

javascript - 在C# Webform(ASP.net)中使用js变量

c# - 如何将带有枚举的 VB.net 接口(interface)转换为 C#

authentication - 将 IPrincipal 从 MVC 传递到 SignalR

sql - 如何向具有大量行的现有数据库表添加标识列

sql-server - tadoquery 发布 : "cannot update non-nullable column with null" on identity column

c# - 如何将屏幕坐标转换成相对坐标(winforms)?

c++ - 确保一个类不是抽象的

c++ - 如何使用字符串返回一个指向对象的唯一指针 vector 的迭代器来查找对象?

JavaScript:在创建的对象上将变量设置为新函数,它仍然调用旧函数

c# - 应用程序级别的通用上下文菜单