PAYLAŞ

Şu ana kadar yaptığımız örneklerde hep önceden hazırlanmış ReadLine()WriteLine() vb. gibi metotları kullandık. Artık kendi metotlarımızı yapmanın zamanı geldi. Bilmem farkında mısınız, ama aslında bütün örneklerimizde birer metot yaratmıştık. O da çalışabilir her programda bulunması gereken Main metoduydu. Artık Main metodu gibi başka metotlar yaratıp programımızın içinde kullanabileceğiz. Metotlar oluşturarak programımızı parçalara böler ve programımızın karmaşıklığını azaltırız. Ayrıca bazı kodları bir metot içine alıp aynı kodlara ihtiyacımız olduğunda bu metodu çağırabiliriz. Bu sayede de kod hamallığı yapmaktan kurtuluruz.

Metot yaratımı ve kullanımı

int MetotAdi(int a,int b)
 {
    return a+b;
 }

Bu metot, iki tane int türünden girdi alır ve bu girdilerin toplamını int türünden tutar. Ancak bu metodu programımız içinde kullanabilmemiz için bu metodun içinde bulunduğu sınıf türünden bir nesne yaratıp “.” operatörüyle bu nesne üzerinden metodumuza erişmeliyiz. Örnek:

using System;
 class Metotlar
 {
    int Topla(int a,int b)
    {
       return a+b;
    }
    static void Main()
    {
       Metotlar nesne=new Metotlar();
       int a=nesne.Topla(2,5);
       Console.Write(a);
    }
 }
  • static olarak tanımlanan metotlara erişmek için metodun içinde bulunduğu sınıf türünden bir nesne yaratmaya gerek yoktur. static olarak tanımlanan metotlara sadece metodun adını yazarak erişilebilir. Örnek:
using System;
 class Metotlar
 {
    static int Topla(int a,int b)
    {
       return a+b;
    }
    static void Main()
    {
       int a=Topla(2,5);
       Console.Write(a);
    }
 }
  • Bütün programlarda önce Main metodu çalışır. Diğer metotlar Main metodunun içinden çağrılmadıkça çalışmaz.
  • Eğer metot, içinde bulunduğumuz sınıfta değil de, başka bir sınıf içinde yaratılmışsa o metodu kullanabilmek için önce sınıfı yazmamız gerekir. Örnek:
 using System;
 class Metotlar1
 {
    public static int Topla(int a,int b)
    {
       return a+b;
    }
 }
 class Metotlar2
 {
    static void Main()
    {
       int a=Metotlar1.Topla(2,5);
       Console.Write(a);
    }
 }

Dikkat ettiyseniz bu metodun yaratılma satırının (4. satır) başına public anahtar sözcüğü konmuş. public sözcüğüyle derleyiciye bu metoda her sınıftan erişilebileceğini söylüyoruz. Eğer public sözcüğü yazılmamış olsaydı bu metoda sadece Metotlar1 sınıfından erişilebilirdi.

  • Şimdi de static olmayan bir metodu başka bir sınıf içinde yaratalım ve kullanalım:
 using System;
 class Metotlar1
 {
    public int Topla(int a,int b)
    {
       return a+b;
    }
 }
 class Metotlar2
 {
    static void Main()
    {
       Metotlar1 nesne=new Metotlar1();
       int a=nesne.Topla(3,9);
       Console.Write(a);
    }
 }
  • Bütün değer tutan metotlar bir değermiş gibi kullanılabilir, ancak değişkenmiş gibi kullanılamaz.
  • Herhangi bir değer tutmayan (WriteLine gibi) metotları void anahtar sözcüğüyle yaratırız. Örnek:
 using System;
 class Metotlar1
 {
    static void Yaz(object a,int b)
    {
       for(;b>0;b--)
          Console.Write(a);
    }
    static void Main()
    {
       Yaz("deneme",5);
    }
 }

Burada oluşturduğumuz Yaz metodu aldığı ilk parametreyi ikinci parametre kere ekrana yazar. Örneğin programımızda “deneme” stringi ekrana 5 kez yazdırılıyor.

  • Herhangi bir değer tutmayan metotlarda return; komutu, yanına herhangi bir ifade olmadan kullanılabilir. Aslında return; komutunun asıl görevi metottan çıkmaktır, ancak yanına bazı ifadeler koyularak metodun tuttuğu değeri belirtme vazifesi de görür. Örneğin bir if koşulu yaratıp, eğer koşul sağlanırsa metottan çıkılmasını, koşul sağlanmazsa başka komutlar da çalıştırılmasını sağlayabiliriz. Ancak doğal olarak bir metodun son satırında return; komutunun kullanılması gereksizdir. Örnek kullanım:
using System;
 class Metotlar1
 {
    static void Yaz(object a,int b)
    {
        if(b>10)
          return;
        for(;b>0;b--)
          Console.Write(a);
    }
    static void Main()
    {
       Yaz('n',10);
    }
 }

Bu programda eğer metoda verilen ikinci parametre 10’dan büyükse metottan hiçbir şey yapılmadan çıkılıyor.

Metotlarla ilgili önemli özellikler

  • Metotları kullanırken parametrelerini doğru sayıda, doğru sırada ve doğru türde vermeliyiz.
  • Değer tutan metotlarda return satırıyla belirtilen ifade, metodu yaratırken verilen türle uyumlu olmalıdır.
  • Değer tutmayan (void ile belirtilmiş) metotlarda return komutunun herhangi bir ifadeyle kullanılması yasaktır.
  • Değer tutmayan metotların bir değermiş gibi kullanılması yasaktır.
  • Metotlar değer tutmayabileceği gibi, parametre de almayabilirler. Örnek program:
using System;
 class Metotlar1
 {
    static void Yaz()
    {
          Console.Write("deneme");
    }
    static void Main()
    {
       Yaz();
    }
 }

Buradaki ekrana “deneme” yazan metot herhangi bir parametre almaz. Dolayısıyla da programda kullanırken de parantezlerin içine hiçbir şey yazılmaz.

  • Bir metodun içinde başka bir metot yaratılamaz. Örneğin aşağıdaki gibi bir kullanım hatalıdır:
 using System;
 class Metotlar1
 {
    static void Yaz()
    {
          Console.Write("deneme");
          static void Ciz()
          {
             Console.Write("\n");
          }
    }
    static void Main()
    {
       Yaz();
    }
 }
  • Metot yaratılırkenki metot parantezinde “static void Yaz(object a,int b)” veya metot küme parantezlerinin içinde tanımlanan değişkenler metottan çıkıldığında bellekten silinirler. Eğer aynı metot tekrar çağrılırsa söz konusu değişkenler tekrar tanımlanıp tekrar değerler atanır.
  • Metot yaratılırkenki metot parantezindeki değişkenlerin türleri tek tek belirtilmelidir. Virgül ile ortak tür belirtimi yapılamaz. Yani static void Ornek(int a,int b) yerine static void Ornek(int a, b)yazılamaz.

Metot parametresi olarak diziler

Örnek:

 using System;
 class Metotlar1
 {
    static void Yaz(int[] dizi)
    {
          foreach(int i in dizi)
             Console.WriteLine(i);
    }
    static void Main()
    {
          int[] dizi={1,2,4,7,9};
          Yaz(dizi);
    }
 }

Buradaki Yaz metodu kendisine parametre olarak verilen dizinin elemanlarını alt alta yazdı. Eğer yalnızca int[] türündeki değil bütün türlerdeki dizileri ekrana yazan bir metot yazmak istiyorsak:

using System;
 class Metotlar1
 {
    static void Yaz(Array dizi)
    {
          foreach(object i in dizi)
             Console.WriteLine(i);
    }
    static void Main()
    {
          int[] dizi={1,2,4,7,9};
          Yaz(dizi);
    }
 }

Bu kullanım doğrudur. Ancak aşağıdaki kullanım hatalıdır:

using System;
 class Metotlar1
 {
    static void Yaz(object[] dizi)
    {
          foreach(object i in dizi)
             Console.WriteLine(i);
    }
    static void Main()
    {
          int[] dizi={1,2,4,7,9};
          Yaz(dizi);
    }
 }

Çünkü dizilerde değişkenlerdeki gibi bir bilinçsiz tür dönüşümünden bahsetmek imkansızdır.

Dizi ve değişken parametreler arasındaki fark

Aşağıdaki iki programı karşılaştırın:

 using System;
 class Metotlar1
 {
   static void Degistir(int[] dizi)    
   {
         for(int i=0;i<5;i++)
             dizi[i]=10;
   }
   static void Yaz(Array dizi)
   {
         foreach(object a in dizi)
             Console.WriteLine(a);
   }
   static void Main()
   {
         int[] dizi={1,2,4,7,8};
         Degistir(dizi);
         Yaz(dizi);
   }
 }
 using System;
 class Metotlar1
 {
   static void Degistir(int sayi)    
   {
         sayi=10;
   }
   static void Yaz(int sayi)
   {
         Console.WriteLine(sayi);
   }
   static void Main()
   {
         int sayi=1;
         Degistir(sayi);
         Yaz(sayi);
   }
 }

Bu iki programı çalıştırdığınızda göreceksiniz ki metoda parametre olarak aktarılan dizinin metot içinde bir elemanının değiştirilmesi esas diziyi etkiliyor. Ancak metoda parametre olarak aktarılan değişkenin metot içinde değiştirilmesi esas değişkeni etkilemiyor. Çünkü bir metoda parametre olarak bir dizi verildiğinde derleyici metoda dizinin bellekteki adresini verir; metot o adresteki verilerle çalışır. Dolayısıyla da dizinin herhangi bir elemanındaki değişiklik esas diziyi etkileyecektir. Çünkü gerek esas program, gerekse de metot aynı adresteki verilere erişir. Halbuki bir metoda parametre olarak bir değişken verdiğimizde metot için değişkenin bellekteki adresi önemli değildir, metot için önemli olan değişkenin değeridir. Metot, değişkeni kullanabilmek için geçici bir bellek bölgesi yaratır ve parametre olarak aldığı değişkenin değerini bu geçici bellek bölgesine kopyalar ve o geçici bellek bölgesiyle çalışır. Metottan çıkıldığında da o geçici bellek bölgesi silinir.

Peki bir metoda aktarılan bir değişkende yapılan bir değişikliğin tıpkı dizilerdeki gibi esas değişkeni etkilemesini ister miydiniz? İşte bunun için C#’ın ref ve out olmak üzere iki anahtar sözcüğü vardır.

ref anahtar sözcüğü

Örnek:

using System;
 class Metotlar1
 {
   static void Degistir(ref int sayi)    
   {
         sayi=10;
   }
   static void Yaz(int sayi)
   {
         Console.WriteLine(sayi);
   }
   static void Main()
   {
         int sayi=1;
         Degistir(ref sayi);
         Yaz(sayi);
   }
 }

ref anahtar sözcüğü değişkenlerin metotlara adres gösterme yoluyla aktarılmasını sağlar. Gördüğünüz gibi ref sözcüğünün hem metodu çağırırken , hem de metodu yaratırken değişkenden önce yazılması gerekiyor. Bu program ekrana 10 yazacaktır. Ayrıca ref sözcüğüyle bir değişkenin metoda adres gösterme yoluyla aktarılabilmesi için esas programda değişkene bir ilk değer verilmelidir. Yoksa program hata verir. Örneğin aşağıdaki program hata verir:

 using System;
 class Metotlar1
 {
   static void Degistir(ref int sayi)    
   {
         sayi=10;
   }
   static void Yaz(int sayi)
   {
         Console.WriteLine(sayi);
   }
   static void Main()
   {
         int sayi;
         Degistir(ref sayi);
         Yaz(sayi);
   }
 }

out anahtar sözcüğü

Kullanımı ref anahtar sözcüğüyle tamamen aynıdır. Tek farkı out ile belirtilen değişkenlere esas programda bir ilk değer verilmesinin zorunlu olmamasıdır. Örneğin aşağıdaki kullanım tamamen doğrudur.

 using System;
 class Metotlar
 {
   static void Degistir(out int sayi)    
   {
         sayi=10;
   }
   static void Yaz(int sayi)
   {
         Console.WriteLine(sayi);
   }
   static void Main()
   {
         int sayi;
         Degistir(out sayi);
         Yaz(sayi);
   }
 }

NOT: ref sözcüğünün dizilerle kullanımı gereksiz olmasına rağmen C# bunu kısıtlamamıştır. Ancak out sözcüğü dizilerle kullanılamaz.

Bir Sonraki derste metotları aşırı yüklenmesi ve diğer metot özellikleri inceleyeceğiz.
NOT:Örnekler güncellenecektir.

3 YORUMLAR

  1. There are some interesting closing dates on this article but I don’t know if I see all of them heart to heart. There is some validity but I’ll take maintain opinion till I look into it further. Good article , thanks and we wish more! Added to FeedBurner as well

BİR CEVAP BIRAK