Herkese merhaba,
Hiç bilmeyenler için değişkenleri, yazılımda herhangi bir veriyi sakladığımız birer kutu gibi düşünebiliriz.
Gerçek hayattan kutu örneğiyle devam edersek; bu kutuların (değişken) içerisinde birer veri saklandığını (değişkenin değeri), kutuların farklı ebatlarda olabileceğini (değişken boyutu), saklanan her verinin farklı tiplerde (değişkenin türü) olabileceğini ve kutuların üstüne de birer isim yazdığımızı (değişkenin adı) düşünebiliriz.
Değişken Tipleri
Şimdi değişkenleri genel olarak bir tabloda, tip, boyut, aralık ve CTS karşılıkları olarak inceleyelim.
TİP | BOYUT (Byte) | ARALIK | CTS Karşılıkları |
byte | 1 | 0-255 | System.Byte |
sbyte | 1 | -128 ile 127 | System.Sbyte |
short | 2 | -32768 ile 32767 | System.Int16 |
ushort | 2 | 0 ile 65535 | System.Uint16 |
int | 4 | -2147483648 ile 2147483647 | System.Int32 |
uint | 4 | 0 ile 4294967295 | System.Uint32 |
long | 8 | -9223372036854775808 ile 9223372036854775807 | System.Int64 |
ulong | 8 | 0 ile 18446744073709551615 | System.Uint64 |
float | 4 | 1.5 x 10-45 ile 3.4 x 1038 | System.Single |
double | 8 | 5.0 x 10-324 ile 1.7 x 10308 | System.Double |
decimal | 8 | 1.0 x 10-28 ile 7.9 x 1028 | System.Decimal |
bool | 1 | True veya False | System.Boolean |
char | 2 | U + 0000-U + FFFF | System.Char |
string | önceden belirlenmemiştir | Metin tutar, belirli bir aralığı yoktur | – |
Yukarıdaki tabloda CTS (Common Type System) karşılıkları kısmında CTS kavramını ilk kez görenler, detaylar için Bir .exe Uygulamasının Anatomisi (CLR, CIL, JIT, CTS Kavramları) başlıklı yazımdaki “CTS (Common Type System) Nedir?” kısmını okuyabilir.
Yukarıdaki tabloya bakarak gerçek hayattan örneklemeye devam edersek tip için kutunun tipini, boyut için kutunun ebatını, aralık için kutunun taşıyabileceği içeriğin hacminin en alt ve en üst limitlerini, CTS karşılıkları için de kutunun evrensel olarak kabul görmüş dünyanın neresine giderseniz gidin kutu dünyasında standartlaşmış bir adı olarak düşünebiliriz.
Akıllara hemen “C#’ta neden farklı farklı değişken tipleri ve bunların farklı boyutları, kapasiteleri var ki? Tek bir tane değişken türü olsa da bu kadar uğraşmasak olmaz mıydı?” gibi bir soru gelebilir. Elbette tek bir veri tipi olması biz yazılım geliştirenlerin işini bir hayli kolaylaştıracaktı ancak yazılım geliştirmede yalnızca kod yazan kişiler olarak kendi kolaylıklarımızdan sorumlu değiliz. Geliştirdiğimiz her yazılımın tükettiği kaynaklar mevcut. Tüketilen kaynakları optimum kullanmak da bizlerin sorumluluğu arasındadır. Elimizdeki kaynakları ne kadar iyi kullandığımız bizlerin ne kadar iyi birer yazılım geliştirici olduğunu gösteren bir faktördür. Önceden belirlenmiş değişken tiplerinin ve boyutlarının olmasının sebebi .NET Framework’ün, yazılım içerisinde kullanacağımız verinin tipini bilmek istemesinden kaynaklanmaktadır. .NET framework veri tipini bilmek istiyor çünkü elindeki memory kaynağını ona göre organize edecektir. Bu sebeple bu kadar farklı veri tipi ve önceden belirlenmiş standart boyutları ve aralıkları bulunmaktadır.
Gerçek hayattan örnek vermemiz gerekirse, evden eve taşıma yapan her şey dahil bir nakliye firmanızın olduğunu ve elinizde büyük küçük çeşitli kamyonetlerin, kamyonların, tırların yer aldığını düşünün. Bir müşterinin sizi aradığını ve eşyasını İstanbul’dan Hakkari’ye taşıtmak istediğini varsayalım. Firma olarak maliyeti belirlemek ve müşteriye de sunduğunuz hizmet için bir fiyat verebilmek için müşterinin eşyasının miktarını bilmeniz gerekir ki buna uygun kamyonet, kamyon veya tır seçip o eşyayı en uygun araca yükleyebilesiniz. Yalnızca bir koltuk ve bir televizyonu olan bir müşteri için koca bir tır’ı İstanbul’dan Hakkari’ye gönderir miydiniz? Yoksa daha uygun ve maliyetinizi azaltacak küçük bir kamyonet işinizi zaten çok güzel görmez miydi? Bu sayede siz kamyoneti yola çıkardığınızda çok daha fazla eşyası olan başka bir müşteri için tırınız hazırda beklerdi 🙂
İşte bu örnekten de anlaşılacağı üzere, .NET Framework de kod yazarken veriyi saklayacağı tipin kendisine bildirilmesini istiyor ki ona uygun hafızada yerini ayırabilsin. Kullanacağınız verinin tipine göre seçim yapmak oldukça isabetli olacaktır.
Value Type ve Reference Type Nedir?
C#’ta tipler “value type (değer tipi)” ve “reference type (referans tipi)” olarak ikiye ayrılır.
Value Type (Değer Tipi): C#’ta kullanılan value type’lar önceden boyutu kesin olarak belirlenmiş, içerisinde direkt olarak veri tutan tiplerdir. Yukarıdaki değişken tablosunda boyut sütununa bir bakalım. Boyutlarının kesin olarak byte karşılıkları yazan değişken tiplerinin hepsi (int, long, float, double, decimal, char, bool, byte, short) birer value type’dır.
Reference Type (Referans Tipi): İçerisinde direkt olarak veriyi değil, verinin tutulduğu hafıza adresini barındıran yani referansını tutan tiplerdir. Yine yukarıdaki değişken tablosuna baktığımızda string’in belirli bir boyutu olmadığını görürüz. Bu sebeple string’e value type diyemeyiz. string bir reference type’dır.
VERİ TİPLERİ | |
VALUE TYPES (DEĞER TİPLERİ) | REFERENCE TYPE (REFERANS TİPLERİ) |
int | string |
long | object |
float | class |
double | interface |
decimal | array |
char | delegate |
bool | pointer |
byte | |
short | |
struct | |
enum | |
GUID |
Kod içerisinde bir tipin value type olup olmadığını öğrenmenin oldukça basit bir yöntemi vardır. Örneğin int tipinin kodda value type olup olmadığını aşağıdaki paylaştığım küçük kod parçası sayesinde öğrenebiliriz.
1 | bool kontrol = typeof(int).IsValueType; |
IsValueType property’si sayesinde bir tipin value type olup olmadığını kolayca öğrenebiliriz.
Stack ve Heap Kavramları Nedir?
Stack ve Heap, memory’de (RAM/bellek) bulunan mantıksal yapılardır. Bu yapıların detaylarına geçmeden önce stack’in kısıtlı ama hızlı, heap’in ise stack’e görece daha geniş bir alana ama yine stack’e göre daha yavaş bir yapıya sahip olduğunu bilmek işimize yarayacaktır.
Stack
- Value Type‘lar (Değer Tipleri) Stack‘te tutulur.
- Stack‘te veriler üst üste ve son giren ilk çıkar (LIFO – Last In First Out) mantığıyla tutulur ve sırası gelmeden aradaki bir değer ile işlem yapılmaz.
- Stack’te bir veriye erişmek, Heap’e göre daha hızlıdır.
- Oluşturulan veriler Stack’in kapsamında çıkınca otomatik olarak yok edilir.
- Program çalışmadan önce Stack’te yer ayrılır. Eğer yazılımı geliştiren kişi tarafından bu bölüm aşılırsa meşhur Stackoverflow hatası ile karşılaşılır.
Heap
- Reference Type‘ların (Referans tiplerin) değeri Heap‘te, değerin Heap‘te saklandığı adresin bilgisi ise Stack‘te tutulur. (Yani bir reference type saklanırken memory’nin hem Heap bölgesi hem de Stack bölgesi kullanılmaktadır. Dikkat edilmesi gereken referans tipin değerinin Heap’te saklanırken, o değerin adresinin Stack’te saklandığıdır.)
- Heap’te veriler karışık bir şekilde tutulur, Stack gibi belirli bir sırada tutulmaz.
- Heap bölgesindeki bir veriye erişmek, Stack’e oranla daha maliyetlidir (yavaştır).
- Heap bölgesindeki bir verinin silinmesi C# için Garbage Collector algoritmasına bağlıdır.
- Program çalıştırılmadan önce yer ayrılmaz, programın çalışma zamanında yer ayrılır.
Boxing ve Unboxing Kavramları Nedir?
Boxing
Boxing işlemi, value type (değer tipi) bir değişkeni, reference type (referans tipi) bir nesneye aktarmaya denir.
1 2 | int sayi = 123; // value type bir degisken tanimlandi object obje = sayi; // bu atamada sayi degiskenine dolaylı olarak (implicity) boxing islemi uygulandi |
Unboxing
Reference type (referans tipi) değişkenin işaret ettiği değeri, value type (değer tipi) bir değişkene aktarmaya denir.
1 2 3 | int sayi1 = 123; //value type degisken tanimlandi ve degeri atandi object obje = sayi1; // Boxing islemi int sayi2 = (int)obje; // Unboxing islemi |
Not: Unboxing işlemi gerçekleştirilirken, boxing işleminde kullanılan veri tipinin aynısının kullanıldığına dikkat edilmelidir. Aksi hale veri tipleri uyuşmayacağından InvalidCastException hatası alınacaktır.
Boxing ve Unboxing Hakkında Ek Bilgiler
- Boxing işlemi, normal bir atama işleminden 20 kat daha uzun sürmektedir.
- Unboxing işlemi, normal bir atama işleminden 4 kat daha uzun sürmektedir.
- Bu sebeplerden dolayı gerekli olmayan aşırı boxing ve unboxing kullanımı uygulamanızı gözle görülür biçimde yavaşlatacaktır.
Veri Serisi‘nin ilk makalesi olan Değişkenler’in böylece sonuna geldik. Herkese keyifli kodlamalar dilerim :)!