Collections Yapıları
Husamettin Elalmis
Merhaba arkadaşlar, bu yazıda sizlere .net frameworkunda kullanılan Collections yapılarından bahsedeceğim. Bunların iyi şekilde kavranılması SOLID prensiplerine göre kod yazılmasını kolaylaştıracaktır.
Collections Nedir?
Verileri liste halinde bellekte barındıran yapılara "Collections" diyoruz
IEnumerable, ICollection, IDictionary, IList gibi yapıların tamamı hiyerarşik olarak birbiri ile ilintilidir. Bunları genellikle backend tarafında sıklıkla kullanırız.
Nerelerde Kullanılır Önemi Nedir?
Collection yapıları, backend tarafında mimari tasarım yaparken kullanılır.
Method içlerinde kullanabiliriz
Repository ve Helper classları içerisinde kullanabiliriz
REST veya WCF servislerinde sıklıkla kullanırız
Methodların dönüş tiplerinin özellikle servis taraflarında kullanımı yaygındır
IEnumerable döndürülebilir
ICollection döndürülebilir
IList/IDictionary döndürülebilir
Backend tasarımında methodların birbirlerine verileri gönderme işlemlerinde bu collectionlar sıklıkla kullanılır
Örneğin bir WCF veya REST servisi geliştiriyor olalım
Geriye List<string> döndürmek yerine IList döndürebiliriz, bu ölçeklenebilir bir yapıdır.
Generic olarak List veya Dictionary döndüren yapılar için ICollection döndürebiliriz, bu ölçeklenebilir bir yapıdır
SOLID prensiblerinin uygulanmasında collectionların doğru kullanımı çok önemlidir, aksi halde ölçeklenebilir yapıdan uzaklaşmış ve sürdürülebilir kod yapısından uzaklaşmış oluruz.
Ölçeklenebilir yapı, mevcut ihtiyaçların karşılanabilmesi ve ilave ihtiyaçların herhangi bir aksaklığa sebebiyet vermeden projeye dahil edilmesi anlamına gelir.
En tepede IEnumerable vardır, ardından ICollection gelir, ardından IDictionary ve IList yapıları gelmektedir.
Kullanılabilen Yapılar
System.Collections sınıfları
ArrayList : Obje veri listesi tutar
HashTable: Key-Value obje listesi tutar
Queue: FIFO (First In First Out) kuralına göre liste tutar
Stack: LIFO (Last In Firt Out) kuralına göre liste tutar
System.Collections.Concurrent sınıfları
ConcurrentDictionary: ThreadSafe işlemlerde kullanılır, dictionary yapısıdır.
System.Collections.Generic sınıfları
IEnumerable<T>: Collections hiyerarşisinin en tepesindedir. ICollection, IList, IDictionary yapılarını kapsar.
ICollection<T>: IEnumerablenin altında yaşar, IList ve IDictionary yapılarını kapsar.
Dictionary<Key,Value>: Generic dictionary yapısıdır
List<T>: Generic list yapısıdır
Queue<T>: Generic queue yapısıdır
SortedList<Key,Value>: Keye göre otomatik sıralanan dictionary yapısıdır
Stack<T>: Generic stack yapısıdır
Array
Dizi olarak kullanılır. Genellikle [] simgesi ile birlikte tanımlarız. Ayrıca Array classı mevcuttur.
private static void ArrayTest()
{
Console.WriteLine("== Array ==");
string[] list = new string[3];
list[0] = "Ankara";
list[1] = "Bolu";
list[2] = "Mardin";
foreach (var item in list)
{
Console.WriteLine(item);
}
}
ArrayList
Dizi olarak kullanılır. İçerisine Obje tipinde her türlü veriyi tutar. Günümüzde, obje tipi yerine generic tipler kullanıldığı için bu yapının kullanımı pek önerilmez, sebebi içerisinde obje barındırdığı içindir. Objenin türünün ne olduğu ayrıca bilmemiz gerekmektedir, bu nedenle bunun yerine List<T> kullanıyoruz.
private static void ArrayListTest()
{
Console.WriteLine("== ArrayList ==");
ArrayList list = new ArrayList();
list.Add("Ankara");
list.Add("Bolu");
list.Add("Mardin");
foreach (var item in list)
{
Console.WriteLine(item);
}
}
StringCollection
ArrayList'in string türlü halidir. İçerisinde barındırılan veri türünün tamamı stringdir. Bunun yerine List<string> kullanıyoruz.
private static void StringCollectionTest()
{
Console.WriteLine("== StringCollection ==");
StringCollection list = new StringCollection();
list.Add("Ankara");
list.Add("Bolu");
list.Add("Mardin");
foreach (var item in list)
{
Console.WriteLine(item);
}
}
StringDictionary
Key ve value tipi string olan bir dictionary türüdür. Bu dictionaryde, keyler otomatik olarak lowercase olmaktadır. Bunun yerine Dictionary<key,value> kullanımı daha uygundur.
private static void StringDictionaryTest()
{
Console.WriteLine("== StringDictionary ==");
StringDictionary list = new StringDictionary();
list.Add("A", "Ankara");
list.Add("B", "Bolu");
list.Add("M", "Mardin");
foreach (string key in list.Keys)
{
Console.WriteLine($"{key} -> {list[key]}");
}
}
Stack
LIFO kuralına göre liste tutar. Push veriyi ekler. Pop veriyi siler.
private static void StackTest()
{
Console.WriteLine("== Stack (LIFO) ==");
Stack stack = new Stack();
stack.Push("Ankara");
stack.Push("Bolu");
stack.Push("Mardin");
while (stack.Count > 0)
{
var res = stack.Pop();
Console.WriteLine(res);
}
}
Queue
FIFO kuralına göre liste tutar. Engueue veriyi ekler. Dequeue veriyi siler.
private static void QueueTest()
{
Console.WriteLine("== Queue (FIFO) ==");
Queue queue = new Queue();
queue.Enqueue("Ankara");
queue.Enqueue("Bolu");
queue.Enqueue("Mardin");
while (queue.Count > 0)
{
var res = queue.Dequeue();
Console.WriteLine(res);
}
}
BitArray
Dizidir, içerisinde Boolean tipinde veri tutar.
private static void BitArrayTest()
{
Console.WriteLine("== BitArray ==");
BitArray arr = new BitArray(5, true);
foreach (var item in arr)
{
Console.WriteLine(item);
}
}
HashTable
Dictionary türüdür, key-value tipinde veri tutar. Verilerin tipi objectdir.
private static void HashTableTest()
{
Console.WriteLine("== HashTable ==");
Hashtable list = new Hashtable();
list.Add("A", "Ankara");
list.Add("B", "Bolu");
list.Add("M", "Mardin");
// yöntem-1 foreach (var key in list.Keys)
{
Console.WriteLine($"{key} -> {list[key]}");
}
Console.WriteLine();
// yöntem-2 var enumerator = list.GetEnumerator(); while (enumerator.MoveNext())
{
Console.WriteLine($"{enumerator.Key} -> {enumerator.Value}");
}
}
SortedList
Dictionary türüdür, key-value tipinde veri tutar. Verilerin tipi objectdir. HashTable'den farkı, veriler eklendiğinde key'e göre otomatik olarak kendi içinde sıralanmaktadır.
private static void SortedListTest()
{
Console.WriteLine("== SortedList ==");
SortedList list = new SortedList();
list.Add("M", "Mardin");
list.Add("A", "Ankara");
list.Add("B", "Bolu");
// yöntem-1 foreach (var key in list.Keys)
{
Console.WriteLine($"{key} -> {list[key]}");
}
Console.WriteLine();
// yöntem-2 var enumerator = list.GetEnumerator(); while (enumerator.MoveNext())
{
Console.WriteLine($"{enumerator.Key} -> {enumerator.Value}");
}
GenericList
Generic liste türüdür. List<T>
private static void GenericListTest()
{
Console.WriteLine("== GenericList ==");
List<string> list = new List<string>();
list.Add("Ankara");
list.Add("Bolu");
list.Add("Mardin");
foreach (string item in list)
{
Console.WriteLine(item);
}
}
Dictionary
Generic liste türüdür. Key-Value ikilisi ile çalışır.
private static void DictionaryTest()
{
Console.WriteLine("== Dictionary ==");
Dictionary<string, string> list = new Dictionary<string, string>();
list.Add("A", "Ankara");
list.Add("B", "Bolu");
list.Add("M", "Mardin");
foreach (var item in list)
{
Console.WriteLine($"{item.Key} -> {item.Value}");
}
}
ICollection
Collection listesidir, IList ve IDictionary'den gelen listeler bu collection türüne assign edilebilir.
private static void ICollectionTest()
{
Console.WriteLine("== ICollection ==");
List<string> list = new List<string>();
list.Add("Ankara");
list.Add("Bolu");
list.Add("Mardin");
ICollection collection = list;
foreach (string item in collection)
{
Console.WriteLine(item);
}
}
IList
Global listedir. Her türlü List<T> bu yapıya assign edilebilir. Bu işlemi genellikle REST/WCF servis yapılarında sıkça kullanırız. Mimari olarak ölçeklenebilir yapıyı mümkün kılar.
private static void IListTest()
{
Console.WriteLine("== IList ==");
List<string> list = new List<string>();
list.Add("Ankara");
list.Add("Bolu");
list.Add("Mardin");
IList ilist = list;
foreach (string item in ilist)
{
Console.WriteLine(item);
}
}
IEnumerable
Global generic listedir, hiyerarşinin en tepesindedir.
private static IEnumerable<string> GetSehirler()
{
List<string> list = new List<string>();
list.Add("Ankara");
list.Add("Bolu");
list.Add("Mardin");
return list;
}
private static void IEnumerableTest()
{
Console.WriteLine("== IEnumerable ==");
var list = GetSehirler(); foreach (string item in list)
{
Console.WriteLine(item);
}
}
SOLID nedir?
SOLID yazılım prensipleri, geliştirilen yazılımın esnek, yeniden kullanılabilir, sürdürülebilir ve anlaşılır olmasını sağlayan, kod tekrarını önleyen prensipler bütünüdür.
SOLID amaçları nelerdir?
Gelecekte gereksinimlere kolayca adapte olması
Yeni özelliklerin kodda değişikliğe gerek kalmadan eklenebilmesi
Yeni özelliklerin kodun en az değişimi yapılarak gerçekleştirilmesi
Kod üzerinde yapılan müdahale ve değişikliklerin minimum zamanda yapılabilinmesinin sağlanması
S = Single-responsibility principle
Bir class, sadece yapması gereken işi yapmalıdır.
Yap: İlgili classların (helpers) iş parçacıklarına bölünerek hazırlanması
Yapma: Tüm methodları tek bir classda toplama
O = Open-closed principle
Bir class, mevcut özelliklerini korumalı, mevcut özelliklerin kaybolmasına izin vermemelidir, değişikliğe izin vermemeli ancak yeni özellikler kazanabiliyor olmalıdır.
Yap: Abstract classları ve Interface yapılarını kulan (OOP Programming)
Yapma: Dümdüz class yazma
L = Liskov substitution principle
Alt classları, üst classların yerine kolayca kullanabilmeliyiz.
Yap: OOP (Object Oriented Programming) yapılarını aktif şekilde kullan
Yapma: Spagetti class yazma
I = Interface segregation principle
Arayüzleri parçalara bölmeliyiz
Yap: Mümkün olduğunda birden fazla Interface'den implement etmeye çalış, böl
Yapma: Tek bir interfaceye tüm methodları koyma
D = Dependency Inversion Principle
Sınıflar arası bağımlılık olabildiğinde az olmalıdır
Yap: Ne kadar çok bölersen o kadar iyidir (N-Tier). DependencyInjection kullanmaya çalış.
Yapma: Farklı uçtaki classları tek bir yerde toplama
Sonuç
Collections yapılarını temel düzeyde örnekleri ile aktarmaya çalıştırm
Backend tarafında bunlar sıklıkla kullanılmaktadır, mimari tasarım unsurları collections yapıları ile yakından ilişkilidir.
IEnumerable nedir?
IList veya ICollection kullanabilir miyiz?
IList ile List<T> arasındaki fark nereden gelir? Kullanım artıları neler olabilir?
Dictionary nedir? Ne amaçla kullanılır?
HashTable nedir?
SortedList nedir?
Dictionary ile ConcurrentDictionary arasındaki fark nedir?
FIFO ve LIFO yapılarını hangi collection türleri destekler?
Diğer collections türleri nelerdir?
SOLID prensipleri nedir?
şeklindeki sorulara daha iyi yanıt vermemizi sağlayan bir dokuman olmasını istedim.
Saygılarımla,
Hüsamettin ELALMIŞ – 08.08.2021
husamettin.elalmis@arksoft.com.tr
Last updated