2011-01-31 4 views
5

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

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

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

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

+3

Какие ресурсы вы боитесь, что использование GUID будет чрезмерно потреблять? Это утверждение немного напоминает преждевременную оптимизацию. Я бы начал с решения, которое использует GUID и только пересматривает его, если вы столкнулись с конкретными узкими местами производительности. –

+0

Я уже думал о проблеме. Спасибо всем за то, что вы меня поймали. –

ответ

13

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

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

private static newObjectId = int.MinValue; 

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

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

+0

Ударьте меня на это. :) –

+0

Хорошо. Вы поместите это в класс, для которого вам нужен идентификатор, и выполните назначение в конструкторе (конструкторах). – KeithS

2

Если уникальность существует только в течение срока действия приложения, не можете ли вы использовать 32-разрядное целое число, инициализированное нулем, а затем просто увеличивать с каждым распределением объектов?

Вам не нужно беспокоиться о TickCount или что-то в этом роде. Число «2» уникально среди чисел; он отличается от «1» и «3», как и от «1203 718», если все, что вы тестируете, - это равенство.

+1

Кое-что о вашем последнем предложении напоминает мне инструкции для Границы священной руки –

3

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

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

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

+1 для блокировки –

8

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

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

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

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

+2

Интересно. Док говорит, что ObjectIDGenerator предназначен для использования в сериализации для времени существования Formatter, который его создал, и работает, поддерживая связь между идентификаторами и адресами объектов. Из описания неясно, будет ли ссылка объекта ObjectIDGenerator на объект предотвращать сбор мусора объекта. Вы знаете, использует ли это слабые ссылки или может быть источником утечки памяти при использовании в течение жизни программы? –

+1

@ Джеффри: Отличная точка. Да, генератор id сохраняет ссылку на объект. Это просто хэш-таблица внутри. –

+0

Сегодня я чему-то научился ... вот почему мне нравится StackOverflow. –

Смежные вопросы