27 Aralık 2010 Pazartesi

Using diğer bir deyişle Try-Finally

Bu yazımızda using ifadesi nedir, ne değildir, ne yapar onu inceleyeceğim... Yine daha önce olduğu gibi basit bir kod yazarak konunun daha anlaşılabilir olmasını istiyorum.

using System.Data;

namespace Using_TryFinally
{
    class Deneme
    {
        static void Main()
        {
            using (DataTable dt = new DataTable())
            { 
            
            }
        }
    }
}


şeklinde hiçbir şey yapmayan bir kodumuz olsun. Bu kodu Visual Studio (VS) ile konsol uygulaması olarak derlediğiniz zaman ortaya çıkan exe'nin kodunu .NET Framework IL Disassembler (IL DASM) açıyoruz. Bu şekilde aslında arka planda neler oluyor, kodumuz ne hale geliyor onu görmüş oluyoruz. Şimdi VS'nin bizim kodumuzu dönüştürdüğü kodu bir inceleyelim:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       29 (0x1d)
  .maxstack  2
  .locals init ([0] class [System.Data]System.Data.DataTable dt,
           [1] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  newobj     instance void [System.Data]System.Data.DataTable::.ctor()
  IL_0006:  stloc.0
  .try
  {
    IL_0007:  nop
    IL_0008:  nop
    IL_0009:  leave.s    IL_001b
  }  // end .try
  finally
  {
    IL_000b:  ldloc.0
    IL_000c:  ldnull
    IL_000d:  ceq
    IL_000f:  stloc.1
    IL_0010:  ldloc.1
    IL_0011:  brtrue.s   IL_001a
    IL_0013:  ldloc.0
    IL_0014:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0019:  nop
    IL_001a:  endfinally
  }  // end handler
  IL_001b:  nop
  IL_001c:  ret
} // end of method Deneme::Main


kod biraz karışık görünüyor olabilirama adım adım incelersek o kadar da karışık bir şey yapmadığını görüyoruz. İlk başta IL_0001 numaralı satırda DataTable objemizin constructor'ı çağırılıyor ve bir altındaki satırda oluşan obje dt isimli değişkenimize aktarılıyor. Daha sonra ise bir try-finally bloğu açılıyor. Biz using ifadesinin içerisine hiçbir şey yazmadığımız için try bloğunun içerisinde hiçbir şey yapılmadığını görüyoruz. Finally bloğunda ise bir şeyler oluyor. Orayı incelediğimizde ise ilk başta yaratılan objemizin null olup olmadığının kontrol edildiğini görüyoruz. Eğer null değilse objemizin Dispose() methodunun çağırıldığını görüyoruz.

Peki biz bu kodu using ifadesini kullanmadan yazmaya kalkarsak ne olur? VB aynı kodunu oluşturur mu onu deneyelim şimdi de. C# kodumuz şöyle olmalı:

using System.Data;

namespace Using_TryFinally
{
    class Deneme
    {
        static void Main()
        {
            DataTable dt = new DataTable();

            try
            {

            }
            finally
            {
                if (dt != null)
                    dt.Dispose();
            }
        }
    }
}


bu kodu derledikten sonra ortaya çıkan .exe'ye IL DASM ile bakıyoruz.

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       31 (0x1f)
  .maxstack  2
  .locals init ([0] class [System.Data]System.Data.DataTable dt,
           [1] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  newobj     instance void [System.Data]System.Data.DataTable::.ctor()
  IL_0006:  stloc.0
  .try
  {
    IL_0007:  nop
    IL_0008:  nop
    IL_0009:  leave.s    IL_001d
  }  // end .try
  finally
  {
    IL_000b:  nop
    IL_000c:  ldloc.0
    IL_000d:  ldnull
    IL_000e:  ceq
    IL_0010:  stloc.1
    IL_0011:  ldloc.1
    IL_0012:  brtrue.s   IL_001b
    IL_0014:  ldloc.0
    IL_0015:  callvirt   instance void [System]System.ComponentModel.MarshalByValueComponent::Dispose()
    IL_001a:  nop
    IL_001b:  nop
    IL_001c:  endfinally
  }  // end handler
  IL_001d:  nop
  IL_001e:  ret
} // end of method Deneme::Main


iki tane fazla üretilen nop komutundan (IL_000b ve IL_001a satırlarında) başka farklılık olmadığını görüyoruz. Nop komutu da aslında bir işlem olmadığından dolayı aslında üretilen iki kodun da birbiri ile aynı olduğunu görüyoruz.

Using ifadesi ile Try-finally bloğu bu şekilde kullanıldığında birbirleriyle tam olarak aynı işlemi yaparlar. Hangisini kullanmak isterseniz kullanabilirsiniz buradan o sonuç çıkıyor. Benim tavsiyem kodun okunabilirliği açısından using kullanmak olacak...

1 yorum:

  1. I love what you guys are usually up too. This sort of clever work
    and exposure! Keep up the awesome works guys I've added you guys to my own blogroll.

    Have a look at my site ... anti cellulite treatment

    YanıtlaSil