Interface'ler Aslında Ne İşe Yarar

21. Şubat 2009

Bana hem eğitimler sırasında hem de bireysel olarak o kadar çok soruldu ki sanıyorum bu konuda birşeyler mutlaka yazmam lazım. Interface kavramının ne olduğunu buradaki yazıda anlatmaya çalışmıştım. Ancak buradaki yazı sadece genel olarak interface kavramını anlatıyor ve bir iki örnek ile konu bitiyordu.

Anladığım kadarı yazı biraz eksik kalmış. Çünkü interface'ler sadece eğlence olsun ya da işi uzatsın diye yazılmaz. En önemli özelliği standardizasyondur. Bu konuyu örnekleyerek devam edelim...

 

Örneğin aşağıdaki gibi bir sınıfımız var.

 

public class ToplamaIslemi
    {
        public int IslemYap(int x, int y)
        {
            return x + y;
        }
    }

Bu basit sınıfımızı örnek olarak hazırladığımız Console uygulamasında aşağıdaki gibi çağırıyoruz.

static void Main(string[] args)
        {
            ToplamaIslemi toplama = new ToplamaIslemi();
            int sonuc = toplama.IslemYap(10, 20);
            Console.WriteLine(sonuc.ToString());
        }

Ve sonuç aşağıdaki gibi oluyor.

 

Bu örnekte ben sınıfın içinde IslemYap isimli bir metod olduğunu biliyordum ve doğrudan sınıf örneği üzerinden bu metodu çağırdım. Peki ya benim çağıracağım sınıfın bu metodu içerip içermediğinden emin değilsem? Yani anlatmak istediğim, modüler bir uygulama geliştirdiniz ve geliştirilen modülün çalışabilmesi için bazı metodları ve özellikleri olması gerekiyor ki sizin uygulamanız ile uyumlu çalışabilsin ama bundan nasıl emin olacaksınız ve bu metodlara nasıl erişeceksiniz.

 

Bu durum da interface'ler size büyük kolaylık sağlar. Örneğin şöyle bir interface hazırlayalım.

interface IMatematikselIslem<T>
    {
        T IslemYap(T x, T y);
    }

Generic özelliğine sahip olan bir interface tanımladık, böylece istediğimiz veri türünü kullanabiliriz. Şimdi  Çarpma, Çıkarma ve Bölme işlemleri için birer sınıf yazalım.

public class CarpmaIslemi : IMatematikselIslem<int>
    {
        public int IslemYap(int x, int y)
        {
            return x * y;
        }        
    }
    public class CikarmaIslemi : IMatematikselIslem<int>
    {

        public int IslemYap(int x, int y)
        {
            return x - y;
        }        
    }
    public class BolmeIslemi : IMatematikselIslem<double>
    {
        public double IslemYap(double x, double y)
        {
            if (y == 0.0)
                throw new DivideByZeroException("Bir sayı sıfıra bölünemez");
            else if (x == 0.0)
                return 0.0;
            else
                return x / y;
        }
    }

Görüldüğü üzere generic yapısını kullanmamız bize bölme işleminde kolaylık sağladı. Tekrar Main() metoduna dönecek olursak,

static void Main(string[] args)
        {
            CarpmaIslemi carpmaIslemi = new CarpmaIslemi();
            BolmeIslemi bolmeIslemi = new BolmeIslemi();
            CikarmaIslemi cikarmaIslemi = new CikarmaIslemi();
            ToplamaIslemi toplamaIslemi = new ToplamaIslemi();

            List<object> islemler = new List<object>(); // işlemleri kolleksiyon halinde saklayacağız
            // tek bir satırda işlemleri atmak için AddRange metodunu kullandık, object dizisini de parametre olarak yolladık.
            islemler.AddRange(new object[] {carpmaIslemi, bolmeIslemi, cikarmaIslemi, toplamaIslemi}); 
            foreach (object islem in islemler)
            {
                //generic tür olarak int alan işlemler
                if (islem is IMatematikselIslem<int>)
                {
                    IMatematikselIslem<int> matIslemi = (IMatematikselIslem<int>)islem;
                    int sonuc = matIslemi.IslemYap(10, 20);
                    Console.WriteLine("Islem: "+ islem.GetType() +", Sonucu:" + sonuc.ToString());
                }
                else if (islem is IMatematikselIslem<double>)
                {
                    // double olarak işlem yapacaksak
                    IMatematikselIslem<double> matIslemi = (IMatematikselIslem<double>)islem;
                    double sonuc = matIslemi.IslemYap(10.0, 2.0);
                    Console.WriteLine("Islem: "+ islem.GetType() +", Sonucu:" + sonuc.ToString());
                }
                else
                {
                    Console.WriteLine("Islem: " + islem.GetType() + " çalıştırılamaz.");
                }
            }            
        }

Görüldüğü üzere Main() metodunu baya değiştirdik, aslında yaptığımız şey basit.

 

  1. Öncelikle  tüm işlemler için bir sınıf örneği oluşturduk.
  2. Ardından object türünden generic bir List kolleksiyonu oluşturduk ve tüm sınıf örneklerini içine AddRange metodu ile attık.
  3. Kolleksiyonumuz içinde foreach ile dönmeye başladık.
  4. Her kayıtta önce if (islem is IMatematikselIslem<int>) kontrolü yaptık. is anahtarı kelimesi bir sınıfın verilen arayüzü (interface'i) uygulayıp uygulamadığını belirlemekte kullanılır ve geriye bool değer döndürür. Burada da IMatematikselIslem arayüzünü <int> türü ile uygulayan olup olmadığını kontrol ettik ve Toplama ile Çıkarma işlemlerini bulduk.
  5. İşlemin uygun olduğunu tespit edince
     IMatematikselIslem<int> matIslemi = (IMatematikselIslem<int>)islem;
    Satırı ile nesnenin arayüze referansını verdik.
  6. Daha sonrada matIslemi arayüz referansı ile aşağıdaki satırı kullanarak IslemYap metodunu çağırdık.
    int sonuc = matIslemi.IslemYap(10, 20);
  7. Sonra da elde ettiğimiz sonucu ekrana yazdık.
  8. Eğer kayıt <int> türünü uygulamamışsa, <double>'ı uygulamış olabilir diye kontrol ettik ve uygun olanlar için 5. , 6. ve 7. adımları uyguladık.
  9. Şayet bu iki kontrolde de başarısız olursa bu işlemin arayüzünü uygulamadığını anlıyoruz ve çalıştırmıyoruz.

 

Aklınıza şu soru gelecektir, niye? Çünkü biz burada IMatematikselIslem arayüzünü uygulamayan ToplamaIslemi sınıfının içinde IslemYap isimli bir metod olduğunu biliyoruz, ama emin miyiz? Ya yoksa, ya da şartlara uymuyorsa. Kodu kendimiz yazmadığımız durumlarda bunu daha iyi anlayabilirsiniz. Programımızı çalıştırınca aşağıdaki gibi bir çıktı oluşturacak

Gördüğünüz gibi oluşturduğumuz arayüz sayesinde, arayüz referansını kullanarak sınıf nesnemizin içinde ki metodu çalıştırdık ve arayüz uygulanmış olduğu içinde istediğimiz gibi olduğuna emin olduk.

 

Son olarak uygulamayı şu şekilde düzenleyelim. Uygulamanın içinde bulunan matematiksel işlem yapan sınıfların her birini ayrı bir DLL haline getirelim ve uygulamamızın bulunduğu dizinde bulunan Islemler içindeki bir klasöre atalım. Daha sonra uygulamadan burada bulunan DLL'leri uygulamaya yükleyelim ve içlerinde bulunan sınıfların metodlarını kontrol ederek çağıralım.

static void Main(string[] args)
        {
            // programın çalıştığı klasörü tespit edip, Moduller klasörünü ekliyoruz.
            string modullerKlasorPath = AppDomain.CurrentDomain.BaseDirectory + "Moduller\\";
            // Bu klasöre ulaşıyoruz
            System.IO.DirectoryInfo modullerKlasoru = new System.IO.DirectoryInfo(modullerKlasorPath);
          // .dll uzantılı dosyaları dolaşıyoruz
            foreach (System.IO.FileInfo dosya in modullerKlasoru.GetFiles("*.dll"))
            {
                // elimizdeki dosyayı Assembly olarak yüklüyoruz.
                System.Reflection.Assembly modul = System.Reflection.Assembly.LoadFile(dosya.FullName);
                // Yüklenen assembly'nin içindeki türleri dolaşıyoruz
                foreach (Type t in modul.GetTypes())
                {
                    // elimizdeki assembly bir sınıfa mı ait yoksa başka bir türe mi (örneğin interface)
                    if (t.IsClass)
                    {                       
                       bool intKontrol = Activator.CreateInstance(t) is IMatematikselIslem<int>;
                       bool doubleKontrol = Activator.CreateInstance(t) is IMatematikselIslem<double>;
                       if (intKontrol)
                       {
                           // bu <int> türünde arayüz uygulanmış bir sınıf, çalıştıralım artık.
                           IMatematikselIslem<int> p = (IMatematikselIslem<int>)Activator.CreateInstance(t);
                                     int sonuc = p.IslemYap(10, 20);
                           Console.WriteLine("Islem:" + t.ToString() + ", sonuç: " + sonuc.ToString());
                       }
                       else if (doubleKontrol)   // double da olabilir.
                       {
                        
                           // bu <double> türünde arayüz uygulanmış bir sınıf, çalıştıralım artık.
                           IMatematikselIslem<double> d = (IMatematikselIslem<double>)Activator.CreateInstance(t);
                         
                               double sonuc = d.IslemYap(10.0, 2.5);
                               Console.WriteLine("Islem:" + t.ToString() + ", sonuç: " + sonuc.ToString());
                       }
                           else
                           {
                               Console.WriteLine(t.ToString() + " türü IMatematikselIslem arayüzünü uygulamadığı için çalıştırılamamaktadır");
                           }
                       
                    }
                }
                
            }            

        }

Bu kodu da çalıştırdığımız zaman aşağıdaki gibi bir çıktı oluşuyor.

 

İnşallah bu sefer Interface (arayüz) kavramını açıklama şansı bulabilmişimdir. Bu uygulamada yapılan iki örneği de aşağıdaki bağlantıyı kullanarak indirebilirsiniz.

 

İndir

Bu yazıyı ilk değerlendiren siz olun

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

.Net Framework, C#



Dinamik Oluşturulan Bir Nesneye Olay Bağlamak

14. Ocak 2009

ASP.Net ile dinamik olarak oluşturduğunuz bir nesneniz olduğunu düşünelim.

Button dugme =  new Button();
dugme.Text = "Bana tıkla";
dugme.Click += new EventHandler(dugmeTiklanmaOlayi);
Form1.Controls.Add(dugme);

Düğmenin tıklanma olayı aşağıdaki gibi olsun,

public void dugmeTiklanmaOlayi(object sender, EventArgs e)
{
Label lblMesaj = new Label();
lblMesaj.Text = "Düğmeye tıklandı";
Form1.Controls.Add(lblMesaj);
}

Düğmeye tıkladığınız zaman bu olayın çalışmadığını göreceksiniz, çünkü ASP.Net ile dinamik olarak oluşturulan nesnelerin olaylarının çalışması için PostBack durumunda OnInit olayının ezilerek kontrolün burada oluşturulması lazım ki Page_Load olayına kadar kontrol ile kontrolün olayı bağlansın. Şayet düğmeyi oluşturma kodunu aşağıdaki gibi OnInit içine alırsanız düğmenizin olayı çalışacaktır.

protected override void OnInit(EventArgs e)
{
Button dugme =  new Button();
dugme.Text = "Bana tıkla";
dugme.Click += new EventHandler(dugmeTiklanmaOlayi);
Form1.Controls.Add(dugme);
}

1 kişi tarafından 5.0 olarak değerlendirildi

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Asp.Net, C#



Generic Bir Liste İçerisinde Arama Yapma

13. Ocak 2009

Aşağıdaki gibi bir sınıfınız varsa,

public class Kisi
{
      public string ID {get; set;}
      public string Ad {get; set;}
      public string Soyad {get; set;}
}

Bu sınıfı aşağıdaki gibi bir kod ile generic türünden bir listeye eklediyseniz.

List<Kisi> kisiler = new List<Kisi>();

kisiler.Add(new Kisi() {ID=1, Ad="Bahadır", Soyad="ARSLAN"});
kisiler.Add(new Kisi() {ID=2, Ad="Evren", Soyad="AYAN"});
kisiler.Add(new Kisi() {ID=3, Ad="Oğuz", Soyad="KOCA"});
kisiler.Add(new Kisi() {ID=4, Ad="Emrah", Soyad="ÇETİNER"});

daha sonra da bu liste içerisinde örneğin bana ID değeri 3 olanı getir dediğinizde uygun kaydın gelmesini istiyorsanız aşağıdaki iki yöntemde arama yapabilirsiniz.

Kisi aranan = kisiler.Find(delegate(Kisi k) { return k.ID == 3;});

veya

Kisi aranan = kisiler.Find(k => k.ID == 1);

 

Bu yazıyı ilk değerlendiren siz olun

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

C#



Sharepoint Hatalarını Event Log'a Yazdırmak

5. Ocak 2009
Daha önceki blog postlarımızda da bahsettiğimiz gibi Sharepoint'te en çok karşılaşılan hata "Unexpected Error" olacaktır. Bu gibi durumlarda özellikle custom geliştirme yaptığınız kod bloklarınızda hata mesajının Event Log'a da yazılmasını sağlamak son derece işe yarar ve geçmişi takip edebileceğiniz bir yapıya kavuşmanızı sağlar.

Bu işlem için .Net Framework içerisinde yer alan System.Diagnostics namespacesini kullanabilirsiniz. Bu sayede uygulamanızın ürettiği hata mesajlarının event loga custom içerikler olarak girilmesini sağlayabilir, gelecek dönemlerde oluşan hataların istatistiklerini çıkarabilirsiniz.

Kullanabileceğiniz örnek hata loglama kodu şu şekilde olabilir.

EventLog.WriteEntry(Source, exceptionString, EventType);

Bu kodu çalıştırdığınızda event kaynağının yaratılmamış olduğuna dair bir hata mesajı alabilirsiniz. Bu durumda ise aşağıdaki kod bloğu ile uygulamanıza spesifik bir event source yaratabilirsiniz.

EventLog.CreateEventSource

Bu yazıyı ilk değerlendiren siz olun

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Asp.Net, C#, Sharepoint



string.format metodunda { (süslü parantez) kullanmak

30. Aralık 2008

string.format metodu .net yazılımcıları için string türündeki verileri daha temiz bir şekilde biçimlendirmeleri için oldukça işe yarayan bir metod.ancak bu metodu kullanırken biçimlendirmek istediğiniz string ifadesinde { (süslü parantez) karakteri geçiyorsa muhtemelen "Input string was not in a correct format Error" hatası alırsınız.bu sorunu çözmek için de, yapılması gereken { ve } karakterini çift olarak kullanmak.örneğin:

_field = string.Format("public {0} {1} {{ get; set; }}", TurDondur(dc.DataType.Name), dc.ColumnName);

Bu yazıyı ilk değerlendiren siz olun

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

C#