9 Ekim 2011 Pazar

C# Boxing ve Unboxing

Kod yazarken başımıza sıkça gelen, belki de bir çoğunda farketmediğimiz olaylardır. Bilinçiz olarak yapılan atamalarda meydana gelirler. Boxing, stack’den heap’e yapılan kopyalamadır. Unboxing, heap’den stack’e yapılan kopyalamadır. Kod yazarken mümkün olduğunca kaçınmamız gereken olaylardır. Performans kaybına neden olurlar çünkü arka tarafta ekstra bir iş yükü getirirler.

İlk olarak bu iki olayı sembolize etmeye çalışalım. Boxing olayı için,

class Program

    {

        static void Main(string[] args)

        {

            int a = 5;

 

            object o = a;

        }

    }

Integer tipindeki nesneler ram’de stack bölgesinde tutulur. int a=5 dediğimiz durumu aşağıdaki gibi sembolize edebiliriz.

image

a adındaki değişkeni object tipinden bir değişkene atadığımız zaman boxing olayı gerçekleşecektir. Çünkü object, nesnesini heap’de tutar. Yani stack’den heap’e bir kopyalama işlemi gerçekleşir.

image

Bu işlemin tam tersini gerçekleştirelim. object tipinden bir değişkende tutulan değeri, integer tipindeki başka bir değişkene atamaya çalışalım.

class Program

    {

        static void Main(string[] args)

        {

            int a = 5;

 

            object o = a;

 

            int b = (int)o;

        }

    }

object tipindeki o adlı değişkende tutulan bir değeri, tekrar integer tipinden başka bir değişkene atmak istersek unboxing olayı gerçekleşecektir.

image

Yukarıdaki örnekler ile boxing ve unboxing olaylarını sembolize etmeye çalıştık. Şimdi de framework içerisinde başımıza gelen bazı olaylara değinelim.

ArrayList koleksiyonunu sıkça kullanırız. İçerisinde object’ler tuttuğundan ötürü eklediğimiz elemanın tipi değer türlü bir tip ise, her eklemede boxing olayı gerçekleşir. Tam tersi durumda, yani okuma işlemi yaptığımızda da geriye object tipinden bir değer döndürdüğünden ötürü, değer türlü tiplere atama yapmamız durumunda unboxing olayı gerçekleşecektir.

class Program

    {

        static void Main(string[] args)

        {

            ArrayList liste = new ArrayList();

            liste.Add(10);

            liste.Add(20);

            liste.Add(DateTime.Now);

            liste.Add(true);

            liste.Add(3.14); //Tüm bu eklemeler sırasında boxing olayı meydana gelecektir. Çünkü ArrayList object tipinden nesneler tutar.

 

            int sayi = (int)liste[0]; //Unboxing olayı gerçekleşir.

 

            DateTime tarih = (DateTime)liste[2]; //Unboxing olayı gerçekleşir.

        }

    }

Son olarak Console sınıfının WriteLine metodunda gerçekleşebilecek bir seneryoya bakalım.

int deger = (int)liste[1];

Console.WriteLine("sayının değeri: {0}", deger.ToString());

“deger” adlı değişkene atama yaparken unboxing olayının gerçekleştiğinden bahsetmiştik. WriteLine metodu içerisine bakarsak, ekrana string bir değer yazdırmak istiyoruz, bunu da formatlı bir şekilde gerçekleştirmeye çalıştık. deger adlı değişken int tipindedir. Ancak içeride ToStiring() metodunu çağırdığımızda boxing olayı meydana gelmektedir.



11 yorum:

Adsız dedi ki...

Çok faydalı bir makale olmuş. Şu şekilde bağlasaydınız daha anlamlı olabilirdi. Boxing/Unboxing i önlemek için .Net Framework 2.0 ile birlikte Generic tipler gelmiştir :)

mdaemon dedi ki...

Bunları kullanmaktan kaçınalım tamam iyi güzel ama bunların yerlerine ne kullanalım?

Onur Salkaya dedi ki...

Merhaba,

Yazının herhangi bir yerinde bunları kullanmayalım gibi bir ibare kullanmadım. Sadece kullanma ihtiyacımız olduğunda arka tarafta gerçekleşen olaylarla ilgili fikir sahibi olmamızda fayda var. İlk yorumda söylendiği gibi, generic tiplerin kullanım amaçlarından biri de budur.

Adsız dedi ki...

hakikaten adam gibi anlatmışsın üstat ... başka yerleri okudumda saçma sapan kelimeler var ve saçma örnekler vermişler yok o oraya başvuruyomuş buraya başvuruyomuş birde kafa karıştırmak için yığın ile öbek diye türkçeye çevirmiş stack heapı çok lazımdı sanki hiç bişey anlamamıştım şimdi anladım az ve öz olmuş ama ufak tefek eksikler var tabi ki .
heap bölgesindeki referans tiplerinin stack bölgesinde bulunan adres tarafından işaret edildiğini başka yerden okumuştum. söylediğin boxing ve unboxing işlemlerinde stack ve heapteki adres yapısını da katarak anlatsan daha açıklayıcı olurmuş yinede eline sağlık

Adsız dedi ki...

Selam,

sanırım generic anlatmak istemişsiniz. Yazınız "Neden boxing unboxing" sorusuna cevap olmamış.

Onur Salkaya dedi ki...

Selamlar,

Bu yazıda sadece boxing ve unboxing kavramlarının ne olduğunu anlatmaya çalıştım. Bunu yaparken de görsel olarak bir şeyler göstermek istedim. Yazının başlığında ya da içeriğinde "Neden boxing unboxing" gibi bir soruya cevap aranmıyor. Zaten bu sorunun da çok mantıklı olduğunu düşünmüyorum.

Ne anlattığımın farkında olacak bilince sahip olduğumu düşünüyorum. Sadece yazının sonunda bu durumun yaşanmaması adına generic tiplerin kullanılabileceği notunu eklemeyi atlamışım. Onu da ilk yorumu yazan arkadaşımızın uyarısı ile fark ettim.

Yine yorumunuz için teşekkürler.

Adsız dedi ki...

Teşekkürler Onur Bey, paylaşımlarınız çok değerli..

Barlas dedi ki...

Teşekkürler Onur Bey

Barlas dedi ki...

Teşekkürler Onur Bey

Adsız dedi ki...

Açıklayıcı bir yazı oldu, emeğinize sağlık.

xyz dedi ki...

çok açıklayıcı teşekkürler

Yorum Gönder