我正在用 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/