Loading...
Elena123456 avatar Elena123456 235 Точки

HashSet and Exception?

Предварително се извинявам за може би малко странния ми въпрос, но тъй като на упражнения не видях никакъв exception при HashSet, искам да се убедя, че правилно съм разбрала- HashSet нямат exceptions?

Опитах да добавям няколко едни и същи стойности в HashSet- не ги дублира, но и не гърми.

Опитах да трия елементи в HashSet, без да проверерям дали въобще ги има- отново не гърми.

От друг форум в тема от преди години, попаднах на следната възникнала грешка на колега при използването на HashSet- "Memory exception", но не ми стана много ясно, като цитирам-  "I get an memory exception while loading a 4GB file. i have to do that twice but i have enougth memmory to load them. the memmory exception occures when i have 3gb left or more."

 

Досега всички изучавани структури от данни са давали exception при един или друг повод, като това са горе-долу грешките на които съм попадала:

Array- ако излезеш от рамките на масива;

List- ако се опитваш да изтриеш елемент, който не съществува или се опиташ да добавиш елемент на несъществуващ индекс;

Dictionary- ако се опиташ да добавиш един и същи Key или се опитваш да изтриеш несъществуващ key;

Stack- опитваш се да Peek() елемент, който го няма, при положение, че Stack вече няма елементи;

Queue- oпитваш се да вземеш или да Peek() елемент, който го няма, при положение, че Queue няма повече елементи;

Поне това е което се сещам, че ми се е случвало, а като стане въпрос за HashSet- абсолютно никакъв exception.

Притеснявам се, че може да има exception, но да го осъзная, чак когато е фатално. smiley

Сега се сетих какво ми се случи при използването на HashSet от обекти- очудващо, че може да дублира имената им, но отново не даде никакъв exception.

 

Тагове:
0
C# Advanced 10/01/2021 12:48:40
VasilKotsev avatar VasilKotsev 830 Точки

Доста старннен въпрос, какво означава: "HashSet нямат Exceptions" ? Hashset-а е оптимизирана колекция, която позволява бързи операции върху уникални елементи. Естествено, че има методи, които хвърлят runtime exceptions. Тук можеш да видиш какви са техните имплементации, къде и при какво поведение се throw-ват exception-и. Например: '.Add(T item)' използва хелпър метод: '.AddIfNotPresent(T value, out int location)' с discard за втория параметър. Там има случай, където ако се опиташ да модифицираш колекцията едновременно, от няколко нишки, е възможно да се throw-не exception, че concurrent операции не се поддържат защото се влиза в безкраен цикъл. Ползват се '.GetHashCode()' и '.Equals(object other)' за да се сравнят обектите когато има колизия между хешовете, защото 'Int32' или неговия alias, в C#, -> 'int', както подсказва името му, е 32 битов целочислен тип данни в .NET CLR-а. Не схващам притеснението, така са преценили да го имлементират. Ако пишеш качествен код и знаеш кога трябва да ползваш сет и кога - не, не бих се притеснявал.

1
10/01/2021 14:29:14
Elena123456 avatar Elena123456 235 Точки

Здравейте и благодаря за скоростния отговор.

 Понеже все още съм в началото на C# Advanced модула, дали може да ми обясните с пример от практиката- кога и защо ще ми се наложи да модифицирам колекция от няколко нишки, че да има възможност от получаването на exception. Може ли да споделите реален пример? Досега не съм успяла да видя какъвто и да е exception при използването на HashSet, а при всички други структури съм получавала многократно. Иначе, знам, че всички типове данни в C# наследяват Оbject и съответно имат Get.HashCode(), Equal() и ToString().

И впрочем от документацията не мога да разбера защо при добавяне на обекти в HashSet аз мога да дублирам имената на обектите, а не се запазват само уникалните такива? Извинявам се и за този странен въпрос, но още съм съвсем в началото и на класовете. 

Поздрави!

0
VasilKotsev avatar VasilKotsev 830 Точки

Конкретен пример от практиката не мога да дам, защото до сега не ми се е налагало в някой проект за клеинт, но за тази цел има т.нар. Concurrent/Thread Safe колекции като например: ConcurrentDictionary<TKey, TVal>, ConcurrentQueue/Stack и още няколко, които никога не съм ползвал. Вариант е да се ползват lock/Monitor statement-и или mutex за да може само една нишка да пипа по колекцията а другите да чакат докато се отключи ресурса, но там вече нещата стават по-завъртяни. Мисля, че имаше и няколко  NuGet пакета, които добавят още thread safe колекции, но не помня точни имена. Както казах поне в моята практика, почти никога не ми се е налагало да ползвам тези колекции.

Относно това, което дадох като пример, просто погледнах source code-a и написах възможен случай. С хешсетове не съм имал каквито и да е проблеми, така, че не съм и задълбавал,къде и какво може да ми хвърли като грешка. Друг е въпроса, че ги няма описани в XML summary-тата... 

За втория въпрос, относно дупликацията на елементите, предполагам не си имплементирала IEquatable<T> в класа, който ползваш. Като generic параметъра е същия като класа, който имплементира интърфейса. Нужно е да напишеш логиката за това как се сравняват обектите, защото по подразбиране се сравняват техните референции, съответно може да имаш 2 инстанции на един обект, с еднакакъв стейт, но с различни адреси. Потърси в google какви са добрите практики да override-неш тези два метода. Не можеш да разчиташ на дефоултните имплементации, които идват от Object.

1
10/01/2021 15:33:08
Elena123456 avatar Elena123456 235 Точки

Наистина оценявам включването Ви в моята тема и благодаря много. Ще потърся за добрите практики, които споменавате. Благодарение на вас вече знам, че HashSet имат exception, но не е често срещан в практиката и  това ме успокоява.  И все пак ако се е случвало на някой от форума да му гръмне HashSet, моля да сподели при какви обстоятелства и как се е справил с проблема.

Поздрави на Вас и много успехи занапред! 

Ели

1
10/01/2021 19:33:35
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.