C#nedir?com
 
YAZAR HAKKINDA
Oğuz Yağmur
Oğuz Yağmur
http://www.oguzyagmur.com
İletişme geçmek için tıklayın.
26 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: aslinda breakpoint degerleri durumda ilgili islemi islemleri istedigimizde private public report results return sirasinda string C# / VC#/.NET Oğuz Yağmur
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : İleri
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 26.9.2007
Okunma Sayısı : 43508
Yorum Sayısı : 2     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
XML - Deniz Kılınç
emre TAŞ
yazının devamı >
emre TAŞ
Decompiling and Reverse Engineering .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Masaüstü mü ? İnternet Mi? .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
.Net Kavramları - .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Yeni Başlayanlar için - .Net Radyo
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer 'in Blogu
ChatBot UI Sample 21.1.2018
Turhal Temizer 'in Blogu
C# – IRR Function 21.1.2018
Burak Selim Şenyurt
Sadece Tarayıcı Kullanarak Web API Servisini Google Cloud Platform Üzerinde Yayınlamak 21.1.2018
Burak Selim Şenyurt
AWS Lambda Üzerinde .Net Core Koşturmak 21.1.2018
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Hata ayıklayıcınızı (debugger) tanıyormusunuz?
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Uygulamarımızı geliştirirken heralde en çok yaptığımız işlemlerin başında hata ayıklama (Debug) işlemleri geliyor. Gerek uygulamamızın hata verdiği durumlarda gerekse uygulamamızdan beklenmedik değerler aldığımızda hatta programlamaya yeni başlayanlar kodların nasıl çalıştığını daha iyi anlayabilmek adına debug işlemleri programcı için büyük kolaylıklar getirmektedir.

Bu makalemizde debug işlemleri yaparken gözden kaçan, aslında yeri geldiğinde işlerimizi büyük oranda kolaylaştıran bazı özelliklere değinip, yeri geldiğinde de debug işlemlerimizi özelleştirmemize yardımcı olacak .Net Framework’ün bize sağladığı imkanlar üzerinde duracağız.Bu özellikler sayesinde debug işlemlerimizin gücünü biraz daha arttırmış olacağız. İlk olarak debug işlemleri sırasında bir dizinin değerlerini görüntülemek istediğimizde aşağıdaki (resim-1) gibi bir görüntü ile karşılaşırız.

ToString() metodu override edilmeden önce
(resim-1)

Oysaki biz dizi elemalarının Type bilgisini (namespace.class_name) görmek yerine daha anlamlı bir veri görmek isteriz. Aslında biliyoruz ki bu bilgi ilgili nesnenin ToString metodunun çağrılması sonucu elde edilmiştir. Bu durumda nesnemizin kodları üzerindeki küçük bir değişiklikle aşağıdaki gibi daha anlamlı ve debug işlemi sırasında zaman kazandıracak bir görüntüyü sağlayabiliriz.
public override string ToString() { return Name; }
Artık debug işlemi sırasında dizi elemanlarımız görüntülenmek istendiğinde ilgili nesnenin ToString() metodu çağrılacak ve sonuçta bizim istediğimiz (override işlemi sonucunda) çıktı debug ekranında (resim-2)belirecektir.


(resim-2)
Görüldüğü gibi küçük işlemler ile daha kolay ve anlaşılır debug işlemleri yapabilmekteyiz. Şimdi de debug işlemleri sırasında işlerimizi kolaylaşatıracak .net framework içindeki bazı niteliklere (Attribute) değinelim.Örneklerimizin açıklamasında kullanacağımız - anlaşılır olabilmesi için -  basit  bir sınıf örneği olarak Ogrenci class'ını yazalım.

[DebuggerDisplay("Ad ={Name},No = {No}")]
public class Ogrenci {
    private string _name;
    public string Name
    {
        [DebuggerStepThrough]
        get { return _name; }
      
        [DebuggerStepThrough]
        set { _name = value; }
    }
    private int _no;
    public int No
    {
        get { return _no; }
        set { _no = value; }
    }
    private int _x;
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public int X
    {
        get { return _x; }
        set { _x = value; }
    }
}
İlk olarak debug işlemi esnasında büyük nesnelerimizin özelliklerini incelemek istediğimizde, nesne üzerine gelip ilgili değerleri arayıp bulur ve inceleriz. Ama aslında biz sadece 2 ya da 3 özelliğin değerini incelemek istediğimizde onca özellik arasından gidip o değerleri bulmak hem sıkıcı hem de zaman alıcı iştir. Tam da  bu  gibi durumlar için DebuggerDisplay niteliği (Attribute) biçilmiş kaftandır. Debug işlemi sırasında nesne üzerine geldiğinizde sadece istediğiniz özelliklerin gösterilmesini sağlar.

Örneğimizde Ogrenci sınıfımıza DebuggerDisplay niteliği uygulanarak debug işlemi sırasında nesne üzerine geldiğimizde sadece Name ve No özelliklerinin (property) istediğimiz bir string formatında görüntülenmesi sağlanmış, sınıfımızın diğer bir üye elemanı olan X özelliği ise devre dışı bırakılmıştır.Tabi ki görüntülenmek istendiğinde nesnenin detayına bakılarak değeri öğrenilebilir. Bu niteliği uygulamadığımız sınıfdan bir nesne debug sırasında aşağıdaki (resim-3) deki gibi görünecektir.


(resim-3)

Diğer bir niteliğimiz ise DebuggerStepThrough; bu nitelik sayesinde debug işlemi esnasında F11 ile dallanma yapmak istediğimizde eğer bizim için önemsiz bir kod bölümü varsa bu kısma dallanma yapmak istemeyeceğimizi belirtebiliriz. Örneğin

Ogrenci o = new Ogrenci();
o.Name = "ali";
o.No = 22;

gibi bir kodu debug ettiğimizi düşünürsek o.Name="ali"; satırında iken F11 ’e bastığımızda Name özelliğinin set metoduna dallanacağını biliyoruz. Fakat DebuggerStepThrough niteliği set için uygulandığından bu dallanma gerçekleşmeyecek o.No=22; kod satırından itibaren debug işlemi devam edecektir. Gerçekten hoş bir nitelik değil mi sizce de.

Diğer niteliğimiz DebuggerBrowsable niteliği.Isminden de açıkça belli olduğu üzere bu niteliğin uygulanmış olduğu nesnenin  özelliği debug ekranında görüntülenmeyecektir. Örneğimize bakacak olursak X özelliğinin debug işlemi sırasında görüntülenmesini istemediğimiz için DebuggerBrowsable niteliğine DebuggerBrowsableState.Never değerini veriyoruz.( Verilebilcek diğer değerler için MSDN'den detaylı bilgi alabilirsiniz.)Çıktımız aşağıdaki resimdeki (resim-4) gibi olacaktır.


(resim-4)

Debug işlemleri sırasında daha etkili debug yapmak ya da belirli durumlar gerçekleştiğinde debug işlemlerimizin geçerli olabilmesi için breakpoint'i biraz daha detaylandırmak gerekecektir. Herhangi bir breakpoint üzerine sağ tıkladığınızda breakpoint üzerine çeşitli işlemler yapabileceğiniz bir menü ile karşılaşacağız. Şimdi bu özellikler ile neler yapabileceğimize bir bakalım.Yine basit ve anlaşılır bir sınıf üzerinde incelememize devam edelim.

public Form1()
{
    InitializeComponent();
    CheckForIllegalCrossThreadCalls = false;
}
private void button1_Click(object sender, EventArgs e)
{
    DoOp();
}
public void DoOp()
{
    Thread th = new Thread(Do);
    th.Name = "debugTest";
    th.Start();
}

int dummyValue = 22;
public void Do()
{
    for (int i = 0; i < 5; i++)
    {
        Text = i.ToString(); //Breakpoint konulan satır
    }
}
İlk bahsedeceğimiz Condition tanımlama işlemi. Eğer belirli bir şarta bağlı olarak debug işlemini gerçekleştirmek istediğimizde bu özelliği aktif hale getirebiliriz. Örnek kodumuz üzerinden açıklamaya çalışırsak; Do metodunda dummyValue değişkenin değeri 22 ise debug işleminin aktif hale gelmesini istiyorum. Bu durumda ilgili breakpoint üzerine sağ tıklayıp çıkan menüden Condition... u seçip aşağıdaki resimdeki (resim-5) gibi  bir şart( Condition ) ekliyorum.


(resim-5)

Artık bu işlemden sonra sadece dummyValue değişkenimin değeri 22 ise breakpoint aktif olacak aksi halde yokmuş gibi varsayılacaktır. breakpoint üzerinde tanımlayabileceğimiz diğer işlem ise Hit Count işlemidir. Debug işlemi sırasında o ana kadar kaç defa breakpoint’e gelindiğini takip etmek ve eğer istersek de "eğer bu breakpoint’e x defa  gelindiğinde artık debug işlemi yapılmasın" da diyebilirsiniz. (Açılan dialog penceresindeki combobox’dan diğer seçenekleri inceleyiniz. (resim-6))


(resim-6)

Diğer bir breakpoint işlemi olan Filter ile belirli filitreler koyarak debug işlemlemini aktif hale getirebiliriz. Aşağıdaki resimde (resim-7) de görüldüğü üzere MachineName,ProcecssId, ProcessName,ThreadId ve ThreadName gibi filitreler koyabileceğimizi görüyoruz.Bizim örneğimizdeki filitrede, eğer bu metod "debugTest" isimli Thread tarafından çağrılmışsa debug işlemi aktif hale gelsin şeklinde bir filitre uygulandığını görüyoruz.


(resim-7)

Son olarak When Hint isimli işlemi inceleceğiz.Debug işlemi aktif hale geldiğinde isterseniz Output Window’a durum bilgilerini yazdırabilir, isterseniz de VS.NET 2005’e ait çeşitli makrolardan birini çağırabilirsiniz. Örneğimizde breakpoint’in hangi metod içinde olduğunu ve bu metodu kimin çağırdığını yazdırıyoruz (resim-8). Ardından da o satırı yorum satırı haline getiren bir makroyu çalıştırıyoruz.


(resim-8)

When Hint tanımlamarımızı yapıp debug modunda uygulamamızı çalıştırdığımızda aşağıdaki gibi (resim-9) bir sonuç aldığımızı göreceğiz.
(resim-9)

Son inceleyeceğimiz konu ise DebuggerTypeProxy ile iç içe geçmiş nesnelerimizi debug işlemi sırasında özelleştirilmiş şekilde görüntülemek olacak. Durumu senaryolaştırmak için aşağıdaki örnek üzerinde açıklamalarda bulunacağız.

[DebuggerTypeProxy(typeof(ReportDebuggerProxy))]
public class Report
{
    private DateTime _date;
    public DateTime ReportDate
    {
         get { return _date; }
         set { _date = value; }
    }
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
    private List _results = new List();
    public List Results
    {
        get { return _results; }
        set { _results = value;}
    }
    private int _dummy;
    public int Dummy
    {
        get { return _dummy; }
        set { _dummy = value; }
    }
 }
Debug şlemleri yaparken sıklıkla karşılştığımızın durumların başında nesnemiz başka bir nesneyi içeriyorsa bu nesneyi ancak hiyeraşik bir biçimde inceleme şansına sahip oluyoruz. Aşağıdaki resimde (resim -10) daha net birşekilde ne demek istediğim belli oluyor.


(resim-10)

Görüldüğü üzere Report türünden r nesnemiz oluşturulmuş ve Results özelliğine 4,2 ve 11 değerleri eklenmiştir. Bu durumda debug sırasında Result’s üyesinin içeriğini görüntülemek için + resmine tıklayıp değerlerini incelemek gerekir.
Bu özellik başka bir nesneyi temsil ediyor, ve o nesne de içerisinde iç içe (nested ) başka değerleri tutuyor olabilir (Dataset->Tables->DataRows... gibi). Bu durumda + lar ile detaylara inip boğulabilirsiniz ki bizim örneğimizde bunları yapsak bile değerlerin Hexdecimal şeklinde olduğunu görüyoruz.

Ama çoğumuz bu iç içe nesnelerin aslında sadece işimize yarayacak kısmını debug işlemi sırasında görmek isteyebilir, hatta bu kısımları özelleştirerek istediğimiz gibi bir görüntü sağlayabiliriz. Aşağıdaki resim ile (resim-11) bir önceki resimi (resim-10)kıyaslayarak debug işlemi sırasındaki görüntüleri karşılaştırabilirsiniz.


(resim-11)

Görüldüğü gibi aslında Report nesnemize ait sadece Name, ReportDate be Results üyelerinin değerleri görüntülenmiş, Results iç içe değil de özel bir biçimde görüntülenmiş, Name özelliğinin değerine "Report Name : " değeri eklenmiştir. Bunu yapabilmek için bu özellikleri içeren ve debug ekranında bu özelliklerin geriye gönderiği değerleri görüntülenecek bir proxy sınıfa ihtiyazcımız var.Aşağıdaki sınıfımız ile bunu gerçekleştiriyoruz.

public class ReportDebuggerProxy
{
    Report _report;
    public ReportDebuggerProxy(Report report)
    {
         _report = report;
    }
     public string ReportDate
    {
        get { return _report.ReportDate.ToLongDateString();}
    }
    public string Name
    {
         get { return "Raport Name : " + _report.Name; }
    }
    public string Results
    {
        get
        {
            StringBuilder sb = new StringBuilder();
            foreach (int result in _report.Results)
            {
                sb.Append("(");
                sb.Append(result.ToString());
                sb.Append(") ");
            }
            return sb.ToString();
        }
    }
 }
Görüldüğü gibi proxy sınıfımız Report sınıfından bir nesne örneği içermekte ve debug işlemi sırasında hangi özellikler görüntülenecekse bunlarla aynı isimli özellikler read-only (sadece okunabilir) olarak yazılmıştır.Report sınıfımızı yazdığımız  koda dikkat ederseniz Dummy isimli bir özellik içermesine karşın buna proxy sınıfında yer verilmemiş bu sayede de debug işlemi sırasında bu özelliğin görüntülenmemesi sağlanmıştır.

Diğer önemli nokta ise Report sınıfındaki bu özelliklerin debug işlemi sırasında nasıl görüntülenmesini istiyorsak proxy sınıfımızdaki özelliklerin get metodunda geriye o şekilde değerler gönderiyoruz. Örneğin proxy sınıfdaki Name özelliği geriye "Report Name : " +....  şeklinde değer döndererek debug işlemi sırasında nasıl görüntüleneceğini (resim -11)kişiselleştirme olanağı sağlamış oluyor geliştiriciye.

Tüm bu özellikleri sağlayabilmek için ise Report sınıfına DebuggerTypeProxy niteliğini uygulamak ve bu niteliğe de proxy sınıfın ne olduğunu bildirmek için de parametre olarak proxy sınıfımızın (ReportDebuggerProxy) tipini paremetre olarak veriyoruz ( typeof(ReportDebuggerProxy) )

Unutmayalım ki hataların tespitinde, bulunan hataların kısa sürede giderilmesinde debug işlemi olmazsa olmazdır. Ve unutmayalım ki iyi debug işlemi yapan bir programcı kendisi ve çevresi için çok zaman kazandıracaktır ;)

Oğuz YAĞMUR
oguz.yagmur@btakademi.com
Makale:
Hata ayıklayıcınızı (debugger) tanıyormusunuz? C#, Visual C# ve .NET Oğuz Yağmur
  • Yazılan Yorumlar
  • Yorum Yaz
EYL
27
2007
Oğuz hocam, Siz de Welcome. Gerçi Sefer hocamdan farklı olarak siz blogunuzu da terketmediğiniz için takip ediyorduk özlü ve çok faydalı makalelerinizi. Ama buradan da fena olmadı hani. Hadi Sefer hocam evlendiği için ara verdi desek siz tosun sahibi olmanıza rağmen ara bile vermeden yazdınız blogunuzda. Tebirkler, hem tosuna hem size :)
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor