Tạo biến mẫu tĩnh và sử dụng Interlocked.Increment(ref nextId)
trên đó.
class Robot {
static int nextId;
public int RobotId {get; private set;}
Robot() {
RobotId = Interlocked.Increment(ref nextId);
}
}
Lưu ý # 1: sử dụng nextId++
sẽ chỉ hợp lệ trong môi trường không đồng thời; Interlocked.Increment
hoạt động ngay cả khi bạn phân bổ rô bốt của mình từ nhiều chuỗi.
EDIT Điều này không giải quyết việc sử dụng lại ID robot. Nếu bạn cần sử dụng lại, giải pháp phức tạp hơn rất nhiều: bạn cần một danh sách các ID có thể sử dụng lại và ReaderWriterLockSlim
xung quanh mã truy cập danh sách đó.
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();
}
}
Lưu ý # 2: Nếu bạn muốn sử dụng lại ID nhỏ hơn trước ID lớn hơn (như trái ngược với cách sử dụng lại ID phát hành trước đó trước khi ID phát hành sau, khi tôi mã hoá nó), bạn có thể thay thế IList<int>
với SortedSet<int>
và thực hiện một vài điều chỉnh xung quanh các phần mà một ID được sử dụng lại được lấy từ bộ sưu tập.
"Nếu sau đó tôi tiêu diệt rô bốt 2 và tạo rô bốt mới sau, nó sẽ có ID là 2." Điều đó không có vẻ giống như khái niệm cơ bản về tăng tự động đối với tôi. – BoltClock
Các phiên bản robot có tồn tại trong một số kho dữ liệu không? SQL Server, Access, v.v. – Bryan