16 Nisan 2011 Cumartesi

C# dilinde Boxing - Unboxing İşlemleri

C# diline yeni başlayanlar şu sözü hep duymuştur: “Her şey bir nesnedir”. Aslına bakarsanız tam olarak öyle değildir. Buna karşın nesneymiş gibi kullanılabilir. Şu makalede açıklamaya çalıştığım değer tipleri ile referans tiplerinin hafızadaki saklanış biçimlerinin birbirinden farklı olduğunu görmüştük. Peki nasıl oluyor da bir değer tipine bir nesne gibi davranabiliyoruz. İşte bu noktada  Boxing kavramı karşımıza çıkıyor.

Boxing tam olarak bir değer tipinin bir object tipine kapalı bir şekilde dönüştürülmesidir. Aşağıda bir boxing ve unboxing işlemi yapılmıştır:

using System;

namespace Boxing
{
    class Program
    {
        static void Main()
        {
            int a = 5; //1

            object b = a; //2 (Boxing)

            int c = (int)b; //3 (Unboxing)
        }
    }
}


Programın 1 ile gösterdiğim kısmında  int tipinde 5 değerine sahip bir a değişkeni tanımlanmış olup, bu tanımlama belleğin stack bölgesinde a için 5 değerine sahip bir yer tahsis edilmesini sağlayacaktır.

2 numaralı kısım ise boxing işleminin yapıldığı yer olup, kapalı bir dönüşüm yapılarak object tipindeki b değişkenine a değişkeni atanmıştır. Bu atama sırasında a değişkeninin değerini içerecek şekilde hafızanın heap bölgesinde bir yer tahsis edilir ve stack bölgesinde bu heap bölgesini işaret edecek şekilde bir referans oluşturulur.

3 numaralı kısım unboxing işleminin yapıldığı satır olup, açık bir tür dönüşüm işlemi yapılmıştır. Burada dikkat edilmesi gereken nokta, türlerin uyumlu olmasıdır. Örneğimizde b değeri zaten bir int değerini işaret ettiğinden bir problemle karşılaşmadık.

Boxing ve unboxing işlemlerini bir de aşağıdaki şekille görelim:

Boxing ve Unboxing işlemleri


Yukarıdaki programımızı derledikten sonra ILDASM aracı ile exe dosyasını incelediğimizde boxing ve unboxing işlemlerini görebiliriz.




Boxing işlemini gerçekten gerekli olan durumlarda kullanmak önemlidir. Bunun nedeni ise normal bir dönüşüme göre boxing işleminin performans kaybına neden olmasıdır. Aşağıdaki kodu inceleyelim:

using System;

namespace BoxingUnboxing
{
    class Program
    {
        static void Boxing()
        {
            int a = 5;
            object b = a;
        }

        static void NormalAtama()
        {
            int a = 5;
            int b = a;
        }

        static void Main()
        {
            //Normal bir atamadaki performans

            DateTime baslangic = DateTime.Now;

            for (int i = 0; i < 60000000; i++)
            {
                NormalAtama();
            }
            DateTime bitis = DateTime.Now;

            TimeSpan performans = bitis - baslangic;

            Console.WriteLine("Normal atama performansı: " + performans.ToString());

            //Boxing kullanılan bir atamadaki performans



            baslangic = DateTime.Now;

            for (int i = 0; i < 60000000; i++)
            {
                Boxing();
            }

            bitis = DateTime.Now;

            performans = bitis - baslangic;

            Console.WriteLine("Boxing performansı: "+ performans.ToString());

            Console.ReadLine();

        }
    }
}

Yukarıdaki programı çalıştırdığınızda normal bir atamanın her zaman boxing kullanılarak yapılan bir atamadan daha performanslı olduğunu göreceksiniz.

C# dilinde Boxing - Unboxing İşlemleri C#, Visual C# Serkan Öztürk

Hiç yorum yok:

Yorum Gönder