22 Nisan 2012 Pazar

C# 'da OOP-2 CTS (Value Type, Reference Type)

CTS (Comman Type System-Ortak Tip Sistemi)
.Net Framework platformunda programlama yapabilmek için ".Net" ortamında yazılmış dillerin uymak zorunda olduğu bazı standartlar vadır. Bu standartlara CLS (Comman Language Specifications-Ortak Dil Özellikleri) denir. CTS kavramı da bu CLS standartları içerisinde yer alır.

DotNet de bulunan tüm dillerde yazılan kodlar ortak bir tip standardına göre ara dile çevrilir. Bu tip standartı CTS 'dir. Böylece farklı dillerde yazılmış olan uygulamalar birbiri ile kolayca haberleşebilir.  Dillerde tanımlamalar farklı olsa bile derlenen kodlar ara koda çevrilirken ortak bir standarda dönüştürülmüş olur Örneğin C# da int, VB.NET de Integer veri tipleri ara koda dönüşürken Int32 olarak dönüştürülür.

Şimdi bu CTS 'nin değişkenlerine ve de bu değişkenlerin C# dahil bir kaç dildeki karşılıklarına bir bakalım.

CTS Data Type
VB .NET
C#
C++
System.Byte
Byte
byte
unsigned char
System.Sbyte
SByte
sbyte
signed char
System.Int16
Short
short
short
System.Int32
Integer
int
int or long
System.Int64
Long
long
__int64
System.UInt16
UShort
ushort
unsigned short
System.UInt32
UInteger
uint
long
System.UInt64
ULong
ulong
unsigned __int64
System.Single
Single
float
Float
System.Double
Double
double
Double
System.Object
Object
object
Object^
System.Char
Char
char
wchar_t
System.String
String
string
String^
System.Decimal
Decimal
decimal
Decimal
System.Boolean
Boolean
bool
Bool


Değişkenler, programımızda geçici olarak değer tutar demiştik yani bilgisayarın ram 'inde tutulurlar. Ram, "stack" ve "heap" bölümlerinden oluşur. Bir değişkenin tipi, değişken tanımlandığında, ram 'in hangi kısmında tutulacağına göre ikiye ayrılır :

  • Value Type (13) : Referans tipler string ve object tipler olmak üzere 2 tanedir. Bu tipler dışındaki 13 adet tip ise, değer tipleridir. Değer tipleri ram 'in "stack" bölümünde tutulurlar. Değer tipleri tanımlandığında, tipine göre, ram 'de belirli bir hafıza rezerv edilir. Bu hafıza alanının, basamak tipi "hexadecimal" olan bir adresi oluşur. Bu adreste de değişkenin değeri tutulur. Değişkenin ömrü tamamlandığında, bu alan serbest bırakılır. Başlangıç değerleri olmak zorundadır, "null" olamazlar.  Değerlerini üzerilerinde taşırlar. Bu yüzden eğer bir değer tipli değişken, diğer değer tipli değişkene atandığında, değişkenlerin değerleri atanmış demektir. Yani eski değişken de değerini saklar ve iki değişkenin değeri de aynı olur. Bunun örneğini de aşağıda görüyoruz arkadaşlar.

            int i = 2;
            int j = i;
            j = 5;
            MessageBox.Show(string.Format("i = {0} ve j = {1}", i, j));
  • Reference Type (2) : Değer tiplerini açıklarken object referans tiptir demiştik. Bundan dolayı class 'lar da referans tiplerdir. Referans tiplerdeki olay ise değişken tanımlandığında, "stack" bölümünde(C++ 'daki pointer 'lar), değişkenin "heap" bölümündeki adresi tutulur. Değişkenin değeri ise "heap" bölümünde tutulur. Bir referans tip tanımlanırken değer almamışsa varsayılan değeri "null" dır. Değeri "null" ise veya "null" değer atanmışsa, o değişkenin değeri yok demektir. Değeri "null" olsa da "stack" bölümünde bir adres tutar. Bu adres , "heap" bölümündeki adresi referans edemeyeceğinden dolayı, "stack" ile "heap" arasında bir bağlantı kurulmamıştır. "Null" bir değişken üzerinde işlem yapılması istenirse, program bize hata verecektir. "Olmayan bir arabamın tekeri" diye bir deyimin hatalı olduğu gibi.
Şimdi bir örnek ile referans tipleri daha yakından inceleyelim. 
            
            Button b1 = new Button();
            b1.Text = "Button1";
            Button b2 = b1;
            b2.Text = "Button2";
            MessageBox.Show(string.Format("b1 = {0} ve b2 = {1}", b1.Text, b2.Text));

"new" diyerek ram 'de bir tane "b1" adında "button" nesnesi oluşturdum. Textine de "Button1" yazdım. Daha sonra "new" anahtar sözcüğünü kullanmadan, "yarım instance" alarak, "b2" adında bir "button" nesnesi tanımladım (dikkat ederseniz oluşturdum demedim). "b2" ye de "b1" butonunu atadım. 

Bu ekran çıktısını açıklamak gerekirse ram 'de şöyle işler meydana geldi : "b2" butonu için ram 'in "heap" bölümünden bir hafıza rezerv edilmedi. Sadece "stack" bölümünden bir adres verildi. Yani bu adresin "heap" bölümünde bir karşılığı yok. Bu bilgilerin ışığında "Button b2 = b1" bu kod satırında butonların textleri birbirine atamadım. Adresi "null" olan "b2" butonuna, "b1" butonun "heap" bölümündeki adresini atadım. Bu yüzden iki buton da "stack" bölümünde, "heap" bölümündeki aynı adresi refere etti. Yani ortada bir buton var ve iki değişken de bu botunu işaret ediyor. Bu örnekten de anlaşılacağı üzere, referans tipler birbirlerine atandığında, property 'leri değil, adresleri birbirine atanır. 

NOT: Referans tiplerde eşitleme adres eşitlemesidir.
NOT: Referans tiplerden string tipi için "null" olmasıyla boş olması ("") arasında büyük fark vardır. Değeri boş olması durumunda "heap" bölümünde yine bir alan rezerve edilir. String 'in uzunluğuna göre de bu alan genişleyebilir.
NOT: Referans tiplerin ömrü bittiğinde "stack" bölümündeki alan iade edilir. Fakat "heap" bölümündeki alan için "Garbage Collector" 'ün (çöp toplayıcı) çalışması beklenir.
NOT: Referans tiplerde "heap" bölümünde ayrılan alanda, "new" anahtar sözcüğü ile oluşturulan class 'ın ve bu class 'ın miras aldığı (inherit ettiği) tüm class 'ların bir instance 'ı (örneği) oluşturulur. Bu örneklerin en alt kısmında da tüm class 'ların atası olan "object" sınıfının adresi bulunmaktadır.  

Bir başka yazıda görüşmek dileğiyle, hoşçakalın...

Hiç yorum yok:

Yorum Gönder