C Sharp Programlama Dili/Örnekler

Vikikitap, özgür kütüphane
Atla: kullan, ara

Bu kısımda yeni bir şey öğrenmeyeceğiz. Sadece önceki gördüğümüz konuları pekiştirecek birkaç örnek yapacağız.

Örnek-1[düzenle]

Bu örneğimizde kendimizi C# programcılarının faydalanması için DLL hazırlayan bir programcı gibi düşüneceğiz. Bu DLL'de bir sınıf ve bu sınıfın içinde de iki metot olacak. Bu metotlardan birisi toplama, birisi çarpma yapacak. Ayrıca DLL'de bu iki metoda ek olarak bu iki metodun isimlerinin listesini tutan bir metot ve DLL'i kullanan programcının parametreye verdiği metoda göre ilgili metodun ne işe yaradığını string olarak tutan bir metot daha olacak. Şimdi DLL'imizi yazmaya başlayabiliriz.

 using System;
 using System.Reflection;
 public class Islem
 {
    [Nitelik("Toplamaya yarar")]
    public static int Topla(int a,int b)
    {
       return a+b;
    }
    [Nitelik("Çarpmaya yarar")]
    public static int Carp(int a,int b)
    {
       return a*b;
    }
    [Nitelik("Bu sınıftaki metotları listeler")]
    public static string MetotListesi()
    {
       Assembly a=Assembly.GetExecutingAssembly();
       Type[] t=a.GetTypes();
       MethodInfo[] mi=t[0].GetMethods(BindingFlags.Static|BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly);
       string GeriDonus="";
       foreach(MethodInfo m in mi)
          GeriDonus+=m.Name+"\n";
       return GeriDonus;
    }
    [Nitelik("Metotlar hakkında bilgi verir.")]
    public static string bilgi(string metot)
    {
       Type t=typeof(Islem);
       MethodInfo mi=t.GetMethod(metot);
       Attribute[] dizi=Attribute.GetCustomAttributes(mi);
       Nitelik a=(Nitelik)dizi[0];
       return ((mi.IsStatic)?"static ":"")+mi.ToString()+" --- "+a.Bilgi;
    }   
 }
 [AttributeUsage(AttributeTargets.Method)]
 class Nitelik:Attribute
 {
    public string Bilgi;
    public Nitelik(string bilgi)
    {
       Bilgi=bilgi;
    }
 }

Bu DLL dosyasını edinen programcının bu DLL dosyasını refere ederek şöyle bir program yazdığını düşünürsek:

 using System;
 class ana
 {
    static void Main()
    {
       Console.WriteLine(Islem.Topla(5,10));
       Console.WriteLine(Islem.Carp(5,10));
       Console.WriteLine(Islem.MetotListesi());
       Console.WriteLine(Islem.bilgi("Topla"));
       Console.WriteLine(Islem.bilgi("Carp"));
       Console.WriteLine(Islem.bilgi("MetotListesi"));
       Console.WriteLine(Islem.bilgi("bilgi"));
    }
 }

Bu programın ekran çıktısı şöyle olur.

15
50
Topla
Carp
MetotListesi
bilgi

static Int32 Topla(Int32, Int32) --- Toplamaya yarar
static Int32 Carp(Int32, Int32) --- Çarpmaya yarar
static System.String MetotListesi() --- Bu sınıftaki metotları listeler
static System.String bilgi(System.String) --- Metotlar hakkında bilgi verir.

Programdaki en kritik nokta

 Nitelik a=(Nitelik)dizi[0];

satırıdır. Burada Attribute türünden olan dizi[0], bu sınıftan türeyen Nitelik sınıfına bilinçli olarak dönüştürüldü. Bilinçsiz dönüştürülemezdi. Ayrıca şu satır da ilginizi çekmiş olmalı:

 MethodInfo[] mi=t[0].GetMethods(BindingFlags.Static|BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly);

Bu satırda ilgili türdeki static, public, static olmayan ve türeyerek gelmemiş olan metotlar mi dizisine atanıyor. Aslında burada tek yapmak istediğimiz object sınıfından gelen metotları elemekti. Ancak bu metot yalnızca BindingFlags.DeclaredOnly'yi kabul etmez. Metotların diğer özelliklerinin de açık şekilde belirtilmesi gerekir. Eğer bu enumu hiç kullanmasaydık bu sefer tüm public metotlar diziye atanacaktı.

Örnek-2[düzenle]

Bu örneğimizde plugin (eklenti) tabanlı bir program yazacağız. Yani isteyen programcılar DLL yazarak programımızın yapabileceği şeyleri artırabilecekler. Sonra yazdıkları DLL'i programımıza tanıtacaklar. Tabii ki DLL'i tanıma işini programımız yapacak. DLL'i yazan kişi sadece programımıza DLL'i tanıma komutu verecek. Ancak programımızın tanıyacağı DLL'in bir standartı olacak. Örneğin metot isimleri, metotların geri dönüş tipleri vs. bizim istediğimiz gibi olacak. Bu yüzden içinde istediğimiz arayüzün olduğu DLL'i programcılar önce edinecek sonra bu arayüze göre DLL'i yazacaklar. Öbür türlü programımızda karmaşa oluşurdu. Şimdi öncelikle içinde arayüzün olduğu ve programcılara dağıtacağımız DLL'imizi yazalım:

Arayüz DLL'ini yazma[düzenle]

 public interface Gereksinimler
 {
    string Bilgi();
 }

Bu dosyayı DLL olarak derleyelim. Gördüğünüz gibi programcıların yazacakları DLL Bilgi() isminde bir metot içermeli. Arayüzler konusundan hatırlayacağınız gibi bir arayüzün elemanları erişim belirleyicisi alamaz ve static olamaz. Ayrıca arayüzü uygulayan sınıf arayüzdeki üyeleri kendine public, static değil, doğru geri dönüş tipinde, parametre sayısı, sırası ve türleri de aynı olacak şekilde geçirmelidir.

Eklentiyi yazma[düzenle]

Şimdi kendimizi eklentiyi yazan programcı yerine koyalım. Arkadaşımızdan arayüz DLL'ini edindik ve bu DLL'e göre DLL'imizi yazacağız. Yine sınıfa Sinif ismini vermemiz gerektiğini arkadaşımızdan öğrendik.

 public class Sinif:Gereksinimler
 {
    public string Bilgi()
    {
       return "Eklentili versiyon.";
    }
 }

Artık eklentiyi yazdık. Tabii ki bu DLL derlenirken arayüz DLL'i ile ilişkilendirilmelidir.

Esas programımızı yazma[düzenle]

Şimdi esas programımıza sıra geldi. Bu program eklenti yükleyip yüklemeyeceğimizi soracak. Eğer yüklemek istersek yolunu isteyecek. DLL'in yolunu verdikten sonra artık programımız ilgili DLL'deki kütüphaneyi kullanabilir hâle gelecek. Şimdi programı yazmaya başlayabiliriz:

 using System;
 using System.Reflection;
 class AnaProgram
 {
    static void Main()
    {
       Console.Write("Eklenti kurmak istiyor musunuz? (e|h): ");
       string a=Console.ReadLine();
       if(a=="h")
       {
          Console.WriteLine("Eklenti kurulmadı.");
          return;
       }
       else if(a=="e")
       {
          EklentiYukleme();
       }
       else
          throw new Exception("Yalnızca e veya h girmeliydiniz.");
    }
    static void EklentiYukleme()
    {
       Assembly a;
       try
       {
          Console.Write("Lütfen DLL dosyasının sabit diskteki adresini girin: ");
          a=Assembly.LoadFrom(Console.ReadLine());
       }
       catch
       {
          Console.WriteLine("Belirttiğiniz dosya yok. Lütfen tekrar deneyiniz.");
          EklentiYukleme();
          return;
       }
       Type[] t=a.GetTypes();
       MethodInfo[] mi=t[0].GetMethods();
       if(t[0].Name!="Sinif"||mi[0].ToString()!="System.String Bilgi()")
          throw new Exception("Eklentideki elemanlar/türler uyumsuz");
       Console.WriteLine(mi[0].Invoke(Activator.CreateInstance(t[0]),null));
    }  
 }

Bu program kullanıcıdan bir DLL dosyası adresi aldı. Bu adresteki DLL'i bir Assembly nesnesi olarak tuttu. Sonra bu Assembly nesnesindeki tipleri bir Type dizisi olarak tuttu. Sonra bu Type dizisinin ilk elemanını bir MethodInfo dizisi olarak tuttu. Sonra ilgili türün ve metot dizisinin ilk elemanının istenildiği gibi olup olmadığı kontrol edildi. Eğer istenilen tür ve metotsa ilgili metot çağrıldı. Eğer istenilen tür ve metot değilse hata verip programı sonlandırdık.

Bu kitabın diğer sayfaları
ASP.NET