Ето няколко съвета, които ще ви помогнат да се справите с по-често срещаните грешки, възникващи при работа с масиви:
-
Когато даден метод връща масив и трябва да върнете празен масив, връщайте масив с 0 елемента, а не null. Когато използвате този метод ще очаквате да се върне масив, макар и с 0 елемента, а не стойност null, ако няма елементи.
-
Не забравяйте, че масивите се предават по референция и затова ако искате да сте сигурни, че даден метод няма да промени даден масив, подавайте на метода копие от масива.
-
Методът Clone() връща плитко копие на масива. Ако елементите на масива са референтни типове, трябва да реализирате собствено дълбоко клониране.
-
При копиране на даден масив в друг използвайте метода Copy(…), а не Clone(). Статичният метод Copy(…) е по-удачен, защото когато е необходимо извършва съответните преобразувания (опаковане и разопаковане) на типовете на елементите на масивите. Ако масивът е от референтни типове, имайте предвид, че Copy(…) създава плитко копие на референциите.
-
Не използвайте метода Array.BinarySearch(…) върху масив, който не е сортиран. Резултатите, които ще върне методът, ако масивът не е сортиран, са трудно предвидими.
-
Когато е възможно използвайте само едномерни, нулево-базирани масиви. CLR е оптимизиран за работа с тях и производителността на вашето приложение ще е много по-добра.
Какво е колекция?
Колекции наричаме класовете, които съдържат в себе си съвкупност от елементи, най-често от един и същи тип. Колекциите са известни още като "контейнер класове" или "контейнери".
Колекциите могат да бъдат с фиксиран размер (такива са например масивите) или с променлив размер (такива са например свързаните списъци). Те могат да бъдат само за четене или да позволяват и промени.
Колекциите са абстрактни типове данни и могат да бъдат имплементирани по различен начин, например: чрез масив, чрез свързан списък, чрез различни видове дървета, чрез пирамида, чрез хеш-таблица и т. н.
Колекциите от обекти са важен елемент в обектно-ориентирания дизайн. Те позволяват даден клас да съдържа множество обекти от даден друг клас. По този начин могат да бъдат моделирани различни взаимоотношения между класовете – асоциации, агрегации, композиции и др.
В .NET Framework класовете, имплементиращи колекции, се намират в пространството от имена System.Collections. Пример за колекция от System.Collections е типът Hashtable. Той имплементира хеш-таблици, които се характеризират с изключително бърз достъп по ключ до съдържаните елементи. Друг пример е ArrayList, който реализира масиви с променлива дължина. Използването на тези и други типове, дефинирани в System.Collections, ни позволява да прекарваме повече време, пишейки код, реализиращ същината на нашето приложение, вместо да си губим времето в опити да реализираме често срещани структури.
Списъчни и речникови колекции
Колекциите в C# са два вида – списъчни и речникови. Списъчните се характеризират с това, че имплементират интерфейсите IList и ICollection. Такива са например ArrayList, Queue, Stack, BitArray и StringCollection. Речниковите колекции имплементират интерфейса IDictionary и по-точно представляват колекция от двойки (ключ, стойност). Примери за такива колекции са класовете Hashtable, SortedList и StringDictionary.
Колекциите са слабо типизирани
Основна характеристика на всички колекции от System.Collections (с изключение на BitArray, който съдържа булеви стойности) е, че те са слабо типизирани – елементите им са от тип System.Object. Слабата типизация позволява на колекциите да съдържат фактически всякакъв тип данни, защото всеки тип данни в .NET Framework наследява System. Object. Ето един пример:
ArrayList list = new ArrayList();
list.Add("beer"); // string inherits System.Object
string s = (string) list[0];
|
За съжаление слабата типизация означава още, че трябва всеки път при достъп до елемент от колекцията да се прави преобразуване на типовете. Както е показано в горния пример за да се достъпи string от ArrayList е необходимо преобразуване.
При съхранение на стойностни типове в колекции се наблюдава намалена производителност, тъй като те се преобразуват в референтни и се прави "опаковане" (boxing) и при преобразуването им обратно към стойностни, съответно – "разопаковане" (unboxing).
За да се избегне преобразуването на типове, може да се използват класовете от System.Collections – CollectionBase и DictionaryBase като базови за силно типизирани потребителски колекции.
В .NET Framework 2.0 ще има типизирани колекции (базирани на т. нар. generics). Те ще наподобяват така наречените шаблони (templates) в C++ и се очаква до голяма степен да решат проблема с намалената производителност и липсата на типизация.
Интерфейсите за колекции
Всички колекции в .NET Framework имплементират един или няколко от интерфейсите IEnumerable, ICollection, IDictionary и IList. На фигурата по-долу е показана клас-диаграма, изобразяваща нагледно йерархията на тези интерфейси:
Нека първо разгледаме интерфейсите IEnumerable и ICollection и обясним за какво служат. На останалите два (IList и IDictionary) ще се спрем малко по-късно.
Интерфейсът IEnumerable
Интерфейсът IEnumerable е базов за всички типове в .NET Framework, които поддържат операцията "обхождане на всичките им елементи". Той дефинира само един метод – методът GetEnumerator(), който връща итератор (инстанция на интерфейса IEnumerator), с който се извършва самото обхождане.
Интерфейсът IEnumerator дефинира методи и свойства за извличане на текущия елемент и за преминаване към следващия (ако има такъв).
Интерфейсът ICollection
Интерфейсът ICollection е базов за всички колекции в .NET Framework. Той разширява IEnumerable и добавя към него свойството Count, което връща общия брой елементи в дадена колекция.
Сподели с приятели: |