Хотите случайное значение или уникальное значение?
случайный! = Уникальный .
Помните, что случайное просто указывает вероятность , а не , генерирующую то же значение, или вероятность генерации того же значения снова . С течением времени вероятность генерирования предыдущего значения возрастает - становится почти наверняка. Что вам нужно?
Лично я рекомендую просто использовать Guid с некоторым контекстом [см. самый простой раздел ниже]. Я также предоставил некоторые другие предложения, чтобы у вас были варианты, в зависимости от вашей ситуации.
простой
Если код представляет собой неограниченную строку [то есть может иметь любую длину], то самым легким разборчивым средством создания уникального кода будет
OrmObject ormObject= new OrmObject ();
string code = string.
Format ("{0} [{1}]", ormObject.Name, Guid.NewGuid ()).
Trim ();
// generates something like
// "My Product [DA9190E1-7FC6-49d6-9EA5-589BBE6E005E]"
Вы можете заменить ormObject.Name
на любую различимую строку. Обычно я использую typeof (objectInstance.GetType ()).Name
, но это будет работать только в том случае, если OrmObject является базовым классом, если это конкретный класс, используемый для всего , все они будут заканчиваться похожими тегами. Смысл в том, чтобы добавить некоторый пользовательский контекст, такой, как, например, в статье wtf , на которую ссылается @Yuriy Faktorovich, - пользователям нужно что-то для чтения.
случайные
Я ответил день или два назад о генерации случайных чисел. Не столько генерация чисел, сколько создание простой гибкой структуры вокруг генератора для улучшения качества кода и данных, это должно помочь упростить ваш источник .
Если вы прочитаете это, вы можете легко написать метод расширения, скажем
public static class IRandomExtensions
{
public static CodeType GetCode (this IRandom random)
{
// 1. get as many random bytes as required
// 2. transform bytes into a 'Code'
// 3. bob's your uncle
...
}
}
// elsewhere in code
...
OrmObject ormObject = new OrmObject ();
ormObject.Code = random.GetCode ();
...
Чтобы создать значение, я бы предложил реализовать интерфейс IRandom
с реализацией System.Security.Cryptography.RNGCryptoServiceProvider
. Упомянутая реализация будет генерировать буфер из X случайных байтов и выдавать столько, сколько потребуется, регенерируя поток при исчерпании.
Более того - я не знаю, почему я продолжаю писать, я думаю, эта проблема действительно очень интересная! - если CodeType является строкой и вы хотите что-то читаемое, вы можете просто взять указанные случайные байты и превратить их в «кажущуюся» читаемую строку с помощью преобразования Base64
public static class IRandomExtensions
{
// assuming 'CodeType' is in fact a string
public static string GetCode (this IRandom random)
{
// 1. get as many random bytes as required
byte[] randomBytes; // fill from random
// 2. transform bytes into a 'Code'
string randomBase64String =
System.Convert.ToBase64String (randomBytes).Trim ("=");
// 3. bob's your uncle
...
}
}
Помните
случайный! = Уникальный .
Ваши значения будут повторяться. В конце концов.
уникальный
Есть ряд вопросов, которые вам нужно задать себе по поводу вашей проблемы.
- Должны ли все
Code
значения быть уникальными? [если нет, ты слишком стараешься]
- Какой тип
Code
? [если строка произвольной длины, используйте полный Guid]
- Это распределенное приложение? [если нет, используйте значение БД, как предложено @LBushkin выше]
- Если это распределенное приложение, могут ли клиентские приложения генерировать и отправлять экземпляры этих объектов? [если это так, то вам нужен глобальный уникальный идентификатор, и снова Guids - верная ставка]
Я уверен, что у вас есть больше ограничений, но это пример того типа запроса, который вам нужно выполнить, когда вы сталкиваетесь с проблемой, подобной вашей. Из этих вопросов вы придумаете ряд ограничений. Эти ограничения проинформируют ваш дизайн.
Надеюсь, это поможет:)
Кстати, вы получите более качественные решения, если опубликуете более подробную информацию [то есть ограничения] по вашей проблеме. Опять же, какой тип Code
, есть ли ограничения по длине? Ограничения формата? Символьные ограничения?
Arg, последнее редактирование, я клянусь . Если вы в конечном итоге используете Guids, вы можете скрыть это или даже «сжать» их представление, кодируя их в base64 - аналогично преобразованию base64, приведенному выше для случайных чисел.
public static class GuidExtensions
{
public static string ToBase64String (this Guid id)
{
return System.Convert.
ToBase64String (id.ToByteArray ()).
Trim ("=");
}
}
В отличие от усечения, преобразование base64 является , а не преобразованием с потерями. Конечно, приведенная выше урезка является проигрышной в контексте полного расширения base64 - но =
- это просто дополнение, дополнительная информация, представленная на преобразование, а не часть исходных данных Guid. Если вы хотите перейти назад к Guid из этого преобразованного значения base64, то вам придется повторно дополнять строку base64, пока ее длина не будет кратна 4 - не спрашивайте, просто посмотрите base64 если вам интересно :)