хэши, наткнулась на статью что хорошо бы у кастомных типов переопределять getHashCode, а дальше запуталась. Потому что подразумевается, вроде как, что у нас уже есть где-то список существующих хэшей и, если наш не уникален, мы чет с этим делаем.
Я думаю, что примерно представляю как это работает внутри дикшинари и хэшсета, там есть список уже имеющихся объектов, но, перееопределяя метод в классе, у меня то его нет
2. Наткнулась на цитату: "Объект ссылочного типа помимо своих полей хранит так называемый заголовок (Header), который состоит из двух полей: указатель на тип которым является данный объект (MethodTablePointer), а так же индекс синхронизации (SyncBlockIndex)"
Не могу найти касается ли это объектов значимого типа тоже. По-идеи, да, раз мы можем получить тип объекта. Но как это происходит внутри? Хидер сразу есть или при подобных запросах среда просто автоматически упаковывает значимый тип в ссылочный и выдает ответ?
1 хеш должен однозначно идентифицировать объект, в идеале хеш у объектов с одинаковым значением свойств должен совпадать, а у объектов с разным значением свойств ВСЕГДА различаться
А как же коллизии?
1. где такое собственно говоря подразумевается? вот тут конкретно https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=net-5.0#notes-to-inheritors написано каким условиям должен обладать хешкод, начинается со слов "A hash function must have the following properties:" 2. нет, не касается
да, но как бы дофига статей про коллизии: var v1 = new KeyValuePair<int, string>(10, "abc"); var v2 = new KeyValuePair<int, string>(10, "def"); Console.WriteLine("v1 - {0}, v2 - {1}", v1.GetHashCode(), v2.GetHashCode()); вернет два одинаковых хэша
да странно что в статье которую выше скинули допускаются коллизии
Тут так умышленно сделано, чтобы хеш считался от ключа
т.е. переопределение гетхэш в кастомных классах — не мастхэв и можно не париться?
ну в этом примере логично, нам же именно по ключам и нужно искать
В структурах желательно, в классах нет
я пыталась нагуглить как решается проблема коллизий, и так и не поняла каким образом мы в результате получаем уверенность, что выданный нашей переопределенной функцией хэш будет уникален
в статье сказано что он не обязан быть уникальным. хеш код НЕ должен быть разным для объектов которые не равны
а что тогда хранят значимые типы помимо своих полей? Как с ними работает определение типа?
разве все поиски по хэшу не строятся на уникальности хэша? в смысле наоборот у объектов, которые не равны, хэш не должен совпадать?
в идеале конечно да, поэтому я и удивился что статья допускает коллизии. но там также сказано что у хорошего хеша должен быть "эффект водопада" - малое изменение исходного объекта должно приводить к большому изменению хеша
вопрос на засыпку - как устроен Dictionary, и почему там вероятность коллизий намного больше чем вероятность коллизий хешкодов?
спасибо, а можно пример переопределенной функции?
насколько помню как список кейвельюпаир, в смысле больше? Мне казалось что вся идея дикшинари, что при добавлении объектов он смотрит на хэш ключа и, если такой уже есть, выдает ошибку. А дальше при поиске по дикшинари как раз происходит тот самый поиск при помощи сравнения хэшей, что экономит ресурс
Если стоит решарпер или райдер, то можно сделать generate equality members и он сам тебе сгенерит
хорошо, где хранятся объекты внутри дикшинари?
это вообще не так работает, если что)
в куче, т.к. дикшинари ссылочный тип.
спасибо, это будет следующим пунктом для гугления
нет, я имею ввиду внутри дикшинари же должен быть какой-то внутренний тип, который хранит наши сущности?
ты имеешь ввиду хэш-таблицу?
масло масляное, нет, оно всё на массивах базируется)
Два массива, Keys, Values
struct не поддерживает полиморфизм, они запечатаны (sealed), поэтому там не нужно определение типа. соответственно, в памяти лежит только само значение
вот тут более подробно рассказывается, хотя и ответ довольно старый https://stackoverflow.com/questions/1769306/why-are-net-value-types-sealed
Ну это неправда (2я половина)
спасибо, но это не отвечает на мой вопрос, вот есть две переменных значимых типов: uint x = 10; int y = 10; сравнение через GetType покажет, что типы переменных разные, значит не только значение лежит в памяти? Или же значение записано в памяти как-то очень специфично, указывая на тип?
должен быть одинаковый для равных, но не обязан быть разный для неравных
сам вызов GetType() приводит к боксингу значения - соответственно, оно помещается в кучу, там же будет информация о типе. по внутреннему лэйауту знакового и беззнакового типов не скажу, может тут в чате есть кто в курсе. но фактически там только само значение лежит, никакой информации о типе дополнительно там нет
вот во что превратится в IL-коде вызов GetType
спасибо огромное!
велкам) обращайтесь!
http://kb.clrium.ru/ru/Memory/01-08-MemoryManagement-RefVsValueTypes.html
Кто-то еще задротит в этот андерхуд? Не понимаю зачем это нужно? Вы там траектории ракет просчитываете?
Обсуждают сегодня