Варианты уникальной идентификации объектов во время выполнения? - PullRequest
5 голосов
/ 31 января 2011

Мне нужно прикрепить уникальный идентификатор к объектам во время выполнения. Идентификатор должен быть уникальным на время действия приложения. Я планирую сделать это, имея личную переменную-член в базовом классе моей объектной модели. Эта переменная будет установлена ​​при инициализации объекта, и значение будет оставаться постоянным в течение всего срока службы объекта. Ни один другой объект не может иметь такой же идентификатор в течение срока действия приложения.

Я, конечно, могу использовать System.Guid , но это стоит 128 бит памяти для каждого объекта, и я хотел бы использовать меньше ресурсов. Я попытался использовать Int32 и инициализировать его с помощью свойства System.Environment.TickCount , но у меня недостаточно разрешения, и некоторые объекты получают одно и то же значение.

В документации для TickCounter говорится, что свойство TickCount будет иметь отрицательное значение через ~ 29, а затем снова обнулится через 29 дней. Я бы с радостью обменял больше разрешения на более короткий ролл со временем.

У меня есть другие варианты, о которых я не знаю?

Ответы [ 4 ]

13 голосов
/ 31 января 2011

Я бы рекомендовал использовать целочисленное значение и автоматически увеличивать его при назначении.Вы можете использовать Interlocked.Increment , чтобы сделать эту операцию безопасной для потока.

Скорее всего, 32-разрядное целое число будет достаточно большим для этой задачи.Я бы порекомендовал что-то вроде:

private static newObjectId = int.MinValue;

private static int GetNextId()
{
    return Interlocked.Increment(ref newObjectId);
}

Затем вы можете использовать это в своем базовом классе для назначения нового уникального идентификатора.

9 голосов
/ 31 января 2011

Для генерации уникальных идентификаторов для объектов вы можете использовать метко названный ObjectIDGenerator , который мы для вас удобно предоставляем:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.objectidgenerator.aspx

Обратите внимание, что, как отмечается в комментарии, генератор идентификатора объекта поддерживает ссылку на объект в действии, поэтому он подходит только для объектов, которые, как вы знаете, в любом случае выживут в жизни приложения. Если вы намереваетесь использовать эту вещь на более эфемерных объектах, тогда это не очень хорошее решение.

Вы можете создать свой собственный генератор идентификаторов объектов, в котором хранятся слабые ссылки; это не будет так сложно.

3 голосов
/ 31 января 2011

Вам нужен идентификатор, чтобы быть уникальным для всех объектов или только для определенного типа?

У вас есть несколько вариантов:

  1. Если вы не переопределите Object.GetHashCode(), это даст вам довольно (но не 100%)надежный идентификатор.Тем не менее, обратите внимание, что (согласно документации), это не гарантировано быть уникальным.Ваши шансы попасть в дубликат, тем не менее, довольно низки.
  2. Если вы (или нуждаетесь в 100%), самым простым решением было бы использовать private static long lastObjectId в вашем классе.Внутри базового конструктора используйте Interlocked.Increment(ref lasObjectId) в качестве значения для текущего объекта.
  3. Если вам нужно, чтобы идентификатор был уникальным для всех объектов, вы можете сделать что-то похожее на 2., новам придется использовать центральный класс для управления этими идентификаторами.
2 голосов
/ 31 января 2011

Если уникальность только для жизни приложения, разве вы не можете использовать 32-разрядное целое число, инициализируемое до нуля, а затем просто увеличивающееся с каждым выделением объекта?о TickCount или что-нибудь в этом роде.Число «2» уникально среди чисел;оно так же отличается от «1» и «3», как и от «1 203 718», если все, что вы проверяете, это равенство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...