Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 12:47
Оценка:
Есть некая система в которой есть группы некоторых объектов. Объекты внутри каждой группы должны уникально идентифицироваться (по крайней мере в пределах этой группы). Причем лучше (удобней и красивей) если это будет происходить автоматически, без участия пользователя этой системы.

Пробовал такой подход:
public SomeObject()
{
...
   this.key = DataTime.Now.Ticks.ToString();
...
}


Но эта фишка, как оказалось, не делает того что нужно — при создании подря нескольких объектов, их поле key инициализируется один и тем же значением. Что, как упоминалось выше, неприемлемо.

Какие здесь возможны подходы?
Re: Как уникально идентифицировать объекты
От: Neco  
Дата: 17.12.07 12:52
Оценка: -2
А>Какие здесь возможны подходы?
GetHashCode()?
всю ночь не ем, весь день не сплю — устаю
Re[2]: Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 12:59
Оценка:
Здравствуйте, Neco, Вы писали:

А>>Какие здесь возможны подходы?

N>GetHashCode()?

Но ведь его тоже надо как-то реализовывать. Среда AFAIK отнюдь не гарантирует уникальность значений по GetHashCode
Re[3]: Как уникально идентифицировать объекты
От: Neco  
Дата: 17.12.07 13:13
Оценка: :)
А> Но ведь его тоже надо как-то реализовывать. Среда AFAIK отнюдь не гарантирует уникальность значений по GetHashCode
меня пока не подводила
я думаю, что GetHashCount базируется на тех же tick'ах, только к ним приплюсовывается к примеру адрес в памяти (я бы примерно так реализовал бы это) — будет фактически уникально, мне кажется.
если хотите можете повысить уникальность через
            object obj = new object();
            Random rnd = new Random(DateTime.Now.Millisecond);
            string uniq = obj.GetHashCode().ToString() + "|" + DateTime.Now.Ticks.ToString() + "|" + rnd.Next(int.MaxValue);


а вообще уникального ничего нет — sequence у оракла тоже не бесконечен, но ведь пользуются и работает же
всю ночь не ем, весь день не сплю — устаю
Re[3]: Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 13:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А> Но ведь его тоже надо как-то реализовывать. Среда AFAIK отнюдь не гарантирует уникальность значений по GetHashCode


просто даже если и перекрыть GetHashCode() и возвращать какой-то намбер на основе полей объекта, то получится так что объекты с одинаковым контентом будут иметь одинкаовый хеш. А мне это в данном случае не надо.
Re[4]: Как уникально идентифицировать объекты
От: Neco  
Дата: 17.12.07 13:18
Оценка:
пардон
почитал насчёт gethashcode — не то, что я думал.

видимо меня всегда выручал тот же sequence
всю ночь не ем, весь день не сплю — устаю
Re[4]: Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 13:19
Оценка:
Здравствуйте, Neco, Вы писали:

А>> Но ведь его тоже надо как-то реализовывать. Среда AFAIK отнюдь не гарантирует уникальность значений по GetHashCode

N>меня пока не подводила
N>я думаю, что GetHashCount базируется на тех же tick'ах, только к ним приплюсовывается к примеру адрес в памяти (я бы примерно так реализовал бы

опыты показывают, что дефолтговый GetHashCode генерит очень "хреново-уникальные-числа". Я точно не помню (пожтому могу слегка наврать), но на 100 объектов он генерит примерно 6 с одинаковым хешем (CLR 2.0)

это) — будет фактически уникально, мне кажется.
N>если хотите можете повысить уникальность через
N>
N>            object obj = new object();
N>            Random rnd = new Random(DateTime.Now.Millisecond);
N>            string uniq = obj.GetHashCode().ToString() + "|" + DateTime.Now.Ticks.ToString() + "|" + rnd.Next(int.MaxValue);
N>


N>а вообще уникального ничего нет — sequence у оракла тоже не бесконечен, но ведь пользуются и работает же


Объекты создаются с малым промежутком времени, поэтому Random rnd = new Random(DateTime.Now.Millisecond); здесь, увы, никак не поможет. тогда уж лучше seed вообще не задавать.
Re: Как уникально идентифицировать объекты
От: Kisloid Мухосранск  
Дата: 17.12.07 13:19
Оценка: 1 (1) +2
Здравствуйте, <Аноним>, Вы писали:

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


Может так?
private Guid guid = Guid.NewGuid();
... << RSDN@Home 1.2.0 alpha rev. 786>>
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re: Как уникально идентифицировать объекты
От: apps Россия  
Дата: 17.12.07 13:21
Оценка: 3 (2)
Здравствуйте, Аноним, Вы писали:

А>Но эта фишка, как оказалось, не делает того что нужно — при создании подря нескольких объектов, их поле key инициализируется один и тем же значением. Что, как упоминалось выше, неприемлемо.


А>Какие здесь возможны подходы?


System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);

Если нужно получить уникальный (в рамках домена Арр-Domain) идентификатор объекта, не следует вызывать метод GetHashCode типа Object.

Этот метод возвращает то же значение, которое возвратил бы метод GetHashCode типа Object; однако, если в типе метод GetHashCode типа Object переопределен, не удастся получить уникальный идентификатор объекта.

Тем не менее в FCL есть метод, который нужно вызывать для получения уникального идентификатора объекта. В пространстве имен System.Runtime.CompilerServices обратитесь к открытому статическому методу GetHashCode класса RuntimeHelpers, который принимает в качестве аргумента ссылку на Object.

Этот метод возвращает уникальный идентификатор для объекта, даже если в типе объекта метод GetHashCode переопределен.

Джеффри Рихтер "CLR via C#"

Если нам не помогут, мы тоже никого не пощадим...
Re: Как уникально идентифицировать объекты
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.12.07 13:23
Оценка: +1
Здравствуйте, Аноним, Вы писали:

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


А>Пробовал такой подход:

А>
А>public SomeObject()
А>{
А>...
А>   this.key = DataTime.Now.Ticks.ToString();
А>...
А>}
А>


А>Но эта фишка, как оказалось, не делает того что нужно — при создании подря нескольких объектов, их поле key инициализируется один и тем же значением. Что, как упоминалось выше, неприемлемо.


А>Какие здесь возможны подходы?


А так:

public static class GlobalCounter
{
    private static uint _value=0;
    public static uint GetNextValue()
    {
        return _value++;
    }
}

...

public SomeObject()
{
...
   this.key = GlobalCounter.GetNextValue();
...
}
Re[2]: Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 13:30
Оценка:
Здравствуйте, Kisloid, Вы писали:

K>Здравствуйте, <Аноним>, Вы писали:


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


K>Может так?

K>
K>private Guid guid = Guid.NewGuid();
K>


как-то жалко использовать гуиды)) ведь они и кончится могут ) Да и потом, вот попользую я их, станут они мне не нужными, а как назад их вернуть я не знаю(((

)))))

А если серьезно. Я это рассматриваю как вариант. Спасибо
Re[5]: Как уникально идентифицировать объекты
От: Neco  
Дата: 17.12.07 13:32
Оценка:
А>Объекты создаются с малым промежутком времени
куда уж меньше, чем в этом примере

        public void MegaTest() {
            for (int i = 0; i < 1000; i++) {
                TestUniq();
            }
        }
        public void TestUniq() {
            Dictionary<string, string> dict = new Dictionary<string, string>(1000);
            Random rnd = new Random(DateTime.Now.Millisecond);
            for (int i = 0; i < 1000; i++) {
                object obj = new object();
                string uniq = obj.GetHashCode().ToString() + "|" + DateTime.Now.Ticks.ToString() + "|" + rnd.Next(int.MaxValue);
                //System.Diagnostics.Debug.WriteLine(uniq);
                dict.Add(uniq, "");
            }
        }


и работает же.
всю ночь не ем, весь день не сплю — устаю
Re[2]: Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 13:36
Оценка:
Здравствуйте, apps, Вы писали:

[]

A>Джеффри Рихтер "CLR via C#"[/q]


Я, ска, знал что что-то такое должно быть ))
Спасибо, камрад!
Re[6]: Как уникально идентифицировать объекты
От: Аноним  
Дата: 17.12.07 13:44
Оценка:
Здравствуйте, Neco, Вы писали:

А>>Объекты создаются с малым промежутком времени

N>куда уж меньше, чем в этом примере

[]

N>и работает же.


Почитай как работает Dictionary да и вообще HashTable. И тебе станет понятно, почему этот пример работает
Re: Как уникально идентифицировать объекты
От: Hike  
Дата: 17.12.07 15:57
Оценка: +1
Здравствуйте, Аноним, Вы писали:

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


А>Пробовал такой подход:

А>
А>public SomeObject()
А>{
А>...
А>   this.key = DataTime.Now.Ticks.ToString();
А>...
А>}
А>


А>Но эта фишка, как оказалось, не делает того что нужно — при создании подря нескольких объектов, их поле key инициализируется один и тем же значением. Что, как упоминалось выше, неприемлемо.


А>Какие здесь возможны подходы?


Можно сделать и так:


public class UniqueBase
{
private static long counter_;
private readonly long _id;

private static long CreateId()
{
return System.Threading.Interlocked.Add(ref counter_, 1);
}

protected UniqueBase()
{
_id = CreateId();
}

public long ID
{
get { return _id;}
}
}

public sealed class Foo : UniqueBase
{
public override string ToString()
{
return ID.ToString();
}
}

Наследуешься от UniqueBase и при создании нового экземпляра будет гарантированно уникальное число (я думаю что диапазона long должно хватить).
Re[7]: Как уникально идентифицировать объекты
От: Neco  
Дата: 17.12.07 18:56
Оценка:
А>Почитай как работает Dictionary да и вообще HashTable. И тебе станет понятно, почему этот пример работает
Dictionary я использовал, чтобы проверить уникальность генерируемого значения.
Вы хотите оспорить уникальность ключа в словаре?
а можно аргументы, примеры?
всю ночь не ем, весь день не сплю — устаю
Re[2]: Как уникально идентифицировать объекты
От: lollipop  
Дата: 18.12.07 08:24
Оценка:
H>Можно сделать и так:


H>public class UniqueBase

H>{
H> private static long counter_;
H> private readonly long _id;

H> private static long CreateId()

H> {
H> return System.Threading.Interlocked.Add(ref counter_, 1);
H> }

H> protected UniqueBase()

H> {
H> _id = CreateId();
H> }

H> public long ID

H> {
H> get { return _id;}
H> }
H>}

H>public sealed class Foo : UniqueBase

H>{
H> public override string ToString()
H> {
H> return ID.ToString();
H> }
H>}

H>Наследуешься от UniqueBase и при создании нового экземпляра будет гарантированно уникальное число (я думаю что диапазона long должно хватить).


+1 .
Только из всего топика так и непонял есть же GUID может можно его использовать? Пусть генерится и сравнивается. Но зато уникальность какая
Re[3]: Как уникально идентифицировать объекты
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 18.12.07 08:30
Оценка: -3
Здравствуйте, lollipop, Вы писали:

L> +1 .

L>Только из всего топика так и непонял есть же GUID может можно его использовать? Пусть генерится и сравнивается. Но зато уникальность какая
Стрельба из пушки по воробьям. Тем более при маленьких объектах — перерасход памяти.
GUID необходимо использовать если объекты будут выходить за пределы одного приложения.
Re: Как уникально идентифицировать объекты
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.12.07 22:08
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Какие здесь возможны подходы?


Все зависит от того, зачем тебе это надо. Если только внутри программы, то сама ссылка на объект — вполне нормальный ключ. Если же планируется этот ключ куда то отдавать за пределы домена, то Guid в большинстве случаев оптимальное решение.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
AVK Blog
Re[3]: Как уникально идентифицировать объекты
От: rgezikov Финляндия  
Дата: 19.12.07 08:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, apps, Вы писали:


А>[]


A>>Джеффри Рихтер "CLR via C#"[/q]


А>Я, ска, знал что что-то такое должно быть ))

А>Спасибо, камрад!

Дурилка картонная этот метод


    Dictionary<int, Object^>^ _crasher = gcnew Dictionary<int, Object^>();
    try
    {
        while(true)
        {
            Object^ obj = gcnew Object();
            int id = RuntimeHelpers::GetHashCode(obj);
            _crasher->Add(id, obj);

            if((_crasher->Count % 10000) == 0)
            {
                Console::WriteLine("Count: {0}", _crasher->Count);
            }
        }
    }
    catch(Exception^ e)
    {
        Console::WriteLine("Exception:\r\n{0}", e);
    }
    finally
    {
        Console::WriteLine("Count: {0}", _crasher->Count);
    }



Exception:
System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at main(String[] args) in c:\rgework\winapi\winapi.cpp:line 51
Count: 5321
Press any key to continue . . .


Такая уникальность нам не нужна! (С) не мой
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.